PowerShell 技能连载 - 向 AD 对象增加自定义属性

如果您想向一个 AD 对象增加自定义属性,只需要用一个哈希表,然后增加期望的属性名和属性值。然后用 Set-ADUser(在随微软免费的 RSAT 工具发布的 ActiveDirectory 模块中)。

这个例子将想当前的用户账户增加两个扩展属性(请确保不要破坏基础环境的属性!请使用测试环境来学习):

#requires -Version 1 -Modules ActiveDirectory
# create an empty hash table
$custom = @{}

# add the attribute names and values
$custom.ExtensionAttribute3 = 12
$custom.ExtensionAttribute4 = 'Hello'

# assign the attributes to your current user object
$user = $env:USERNAME
Set-ADUser -Identity $user -Add $custom

选择正确的参数很重要。用 -Add 参数向属性增加新的值用 -Remove 移除一个已有的值用 -Replace 将属性替换为一个新的值。

PowerShell 技能连载 - 复制 Active Directory 安全设置

当您向一个 AD 对象增加委派权限(例如允许一个用户管理一个组织对象的成员)时,实际上是调用了该 AD 对象的改变安全设置方法。

AD 安全描述符有可能非常复杂。复制 AD 安全信息却非常简单。所以如果您希望将相同的安全设置复制到另一个 AD 对象,您可以从一个对象读取已有的安全设置,然后将它们复制到另一个对象上。

这段脚本演示了如何从一个 OU 读取安全设置,并且将它复制到另一个 OU。这需要随 ActiveDirectory 模块发布的 ActiveDirectory 提供器。这个模块是微软免费的 RSAT 工具的一部分,需事先安装。

#requires -Version 2 -Modules ActiveDirectory
Import-Module -Name ActiveDirectory

# read AD security from NewOU1
$sd = Get-Acl -Path 'AD:\OU=NewOU1,DC=powershell,DC=local'

# assign security to NewOU2
Set-Acl -Path 'AD:\OU=NewOU2,DC=powershell,DC=local' -AclObject $sd

PowerShell 技能连载 - 将命令历史保存到文件

随着 PowerShell 3.0 及以上脚本发布的 PowerShell ISE 内置编辑器可以支持定制,并且可以增加自己的菜单项。

当您运行以下代码时,您会发现在“附加工具”菜单中会多出一个“Get Command History”子菜单,也可以通过 ALT + C 组合键激活该功能。

这个命令将返回当前的命令行历史(您在当前 ISE 会话中交互式键入的命令)并且将它们拷贝到一个新的 PowerShell 文件中。通过这种方式,可以很轻松地保存互操作的历史。您甚至可以通过这种方式自动创建 PowerShell 脚本:只需要删掉不能用的代码行,只留下能产生预期结果的代码行。

#requires -Version 3
$code =
{
    $text = Get-History |
    Select-Object -ExpandProperty CommandLine |
    Out-String

    $file = $psise.CurrentPowerShellTab.Files.Add()
    $file.Editor.Text = $text
}

$psise.CurrentPowerShellTab.AddOnsMenu.Submenus.Add('Get Command History', $code, 'ALT+C')

PowerShell 技能连载 - 简单的 AD 组管理

假设您已下载安装了微软免费的 RSAT 工具,那么管理 AD 组合组成员会相当轻松。以下几行代码演示了如何入门:

#requires -Version 1 -Modules ActiveDirectory
# create new AD group
New-ADGroup -DisplayName PowerShellGurus -GroupScope DomainLocal -Name PSGurus

# get group
Get-ADGroup -Identity PSGurus -Credential $cred -Server 172.16.14.53


# select users by some criteria
$newMembers = Get-ADUser -Filter 'Name -like "User*"'

# add them to new AD group
Add-ADGroupMember -Identity 'PSGurus' -Members $newMembers

# list members of group
Get-ADGroupMember -Identity PSGurus

PowerShell 技能连载 - 使用 PowerShell 的帮助

要查看完整的 PowerShell 帮助,您首先需要从 Internet 下载帮助信息。只需要以管理员权限打开一个 PowerShell 控制台执行以下代码:

PS> Start-Process -FilePath powershell.exe -Verb runas

下一步,下载 PowerShell 帮助:

PS> Update-Help -UICulture en-us -Force

请注意:PowerShell 帮助只有英语的版本。这是为什么要指定 -UICulture 确保请求下载英文帮助文件的原因。

当帮助文件安装完后,在 PowerShell 4.0 及以上版本就可以使用了。您可以显示一个命令的完整帮助,或只是显示示例代码:

PS> Get-Help -Name Get-Random -ShowWindow

PS> Get-Help -Name Get-Random -Examples

NAME
    Get-Random

SYNOPSIS
    Gets a random number, or selects objects randomly from a collection.

    -------------------------- EXAMPLE 1 --------------------------

    PS C:\>Get-Random
    3951433


    This command gets a random integer between 0 (zero) and Int32.MaxValue.




    -------------------------- EXAMPLE 2 --------------------------

    PS C:\>Get-Random -Maximum 100
    47


    This command gets a random integer between 0 (zero) and 99.



   ...

在 PowerShell 3.0 中,如果您并不是使用英语,您需要手动将帮助文件从 en-US 文件夹复制到您语言对应的文件夹中:

#requires -RunAsAdministrator
#requires -Version 3

$locale = $host.CurrentUICulture.Name
if ($locale -eq 'en-us')
{
    Write-Warning 'You are using the English locale, all is good.'
}
else
{
    Copy-Item -Path "$pshome\en-us\*" -Destination "$pshome\$locale\" -Recurse -ErrorAction SilentlyContinue -Verbose
    Write-Host "Help updated in $locale locale"
}

当帮助文件复制到您语言对应的文件夹中后,您就可以在非英语系统中使用英语的帮助文件了。

PowerShell 技能连载 - 设置 AD 账号的过期时间

要安全地使用临时的 AD 账号,例如给客户或是顾问使用,请记得设置一个失效日期。

以下示例代码演示了如何设置今天起 20 之后过期:

#requires -Version 1 -Modules ActiveDirectory
# SAMAccount name
$user = 'user12'

# days when to expire
$Days = 20

# expiration date is today plus the number of days
$expirationDate = (Get-Date).AddDays($Days)

Set-ADUser -Identity $user -AccountExpirationDate $expirationDate

请注意这段代码需要随 RSAT 免费工具发布的 Active Directory 模块。

如果您的计算机并没有连接到 AD,但是您拥有一个合法的 AD 账号,您可以用这种方法手动连接到 AD:

#requires -Version 1 -Modules ActiveDirectory

# Name or IP of DC
$ServerName = '10.10.12.110'
# Logon credentials
$Credential = Get-Credential


# SAMAccount name
$user = 'user12'

# days when to expire
$Days = 20

# expiration date is today plus the number of days
$expirationDate = (Get-Date).AddDays($Days)

Set-ADUser -Identity $user -AccountExpirationDate $expirationDate -Server $ServerName -Credential $Credential

PowerShell 技能连载 - 批量删除 AD 的防意外删除保护

缺省情况下,AD 对象是受保护防止意外删除的。要移除一个指定的范围内所有对象(例如某个机构之下)的这种保护,请试试这段代码:

#requires -Version 1 -Modules ActiveDirectory

Get-ADObject -Filter * -SearchBase 'OU=TestOU,DC=Vision,DC=local"' |
ForEach-Object -Process {
    Set-ADObject -ProtectedFromAccidentalDeletion $false -Identity $_
}

注意:这段代码需要免费的 RSAT 工具所带的 ActiveDirectory 模块。

PowerShell 技能连载 - AD 操作自动化入门

当 Microsoft 下载的免费的 RSAT 工具包含了 ActiveDirectory 模块。它带有一系列管理 Active Directory 账户的命令。

假设您已经连入了一个 Active Directory 环境,您可以使用以下示例代码来熟悉这些新命令:

# find your own user account by SAMAccountName
Get-ADUser -Identity $env:USERNAME

# find user account by DN
Get-ADUser -Identity 'CN=TWeltner,OU=Users,OU=Hannover,OU=Trainees,DC=powershell,DC=local'

# find your own user account and return all available attributes
Get-ADUser -Identity $env:USERNAME -Properties *

# find your own user account and change attributes
Get-ADUser -Identity $env:USERNAME | Set-ADUser -Description 'My account'

# find all user accounts where the SAMAccount name starts with "T"
Get-ADUser -Filter 'SAMAccountName -like "T*"'

# find user account "ThomasP" and use different logon details for AD

# logon details for your AD
$cred = Get-Credential
$IPDC = '10.10.11.2'
Get-ADUser -Identity ThomasP -Credential $cred -Server $IPDC

# find all groups and output results to gridview
Get-ADGroup -Filter * | Out-GridView

# find all groups below a given search root
Get-ADGroup -Filter * -SearchBase 'OU=test,DC=powershell,DC=local'

# get all members of a group
Get-ADGroupMember -Identity 'Domain Admins'

# create new user account named "Tom"
# define password
$secret = 'Initial$$00' | ConvertTo-SecureString -AsPlainText -Force
$secret = Read-Host -Prompt 'Password' -AsSecureString
New-ADUser -Name Tom -SamAccountName Tom -ChangePasswordAtLogon $true -AccountPassword $secret -Enabled $true

# delete user account "Tom"
Remove-ADUser -Identity Tom -Confirm:$false

# create an organizational unit named "NewOU1" in powershell.local
New-ADOrganizationalUnit -Name 'NewOU1' -Path 'DC=powershell,DC=local'

# all user accounts not used within last 180 days
$FileTime = (Get-Date).AddDays(-180).ToFileTime()
$ageLimit = "(lastLogontimestamp<=$FileTime)"
Get-ADUser -LDAPFilter $ageLimit

PowerShell 技能连载 - 设置本地 Administrator 账号的密码

要操作本地用户账号并设置一个新密码,您可以使用底层的 WinNT: 命名空间。

请注意,您需要管理员权限来设置新密码。

这个脚本可以为本地 Administrator 账号设置密码:

#requires -Version 1
$Password = 'P@ssw0rd'

$admin = [adsi]("WinNT://$env:computername/administrator, user")
$admin.psbase.invoke('SetPassword', $Password)

PowerShell 技能连载 - 加密文本

有很多办法可以加密文本。以下是一个未使用“密钥”的方法,所谓的密钥实际上是您的用户标识符加上机器名。

当您使用 ConvertTo-TextEncrypted 命令加密文本时,结果只能由同一个人在同一台机器上使用 ConvertFrom-TextEncrypted 命令来解密:

#requires -Version 2


function ConvertTo-TextEncrypted
{
    param([Parameter(ValueFromPipeline = $true)]$Text)

    process
    {
        $Text |
        ConvertTo-SecureString -AsPlainText -Force |
        ConvertFrom-SecureString
    }
}


function ConvertFrom-TextEncrypted
{
    param([Parameter(ValueFromPipeline = $true)]$Text)

    process
    {
        $SecureString = $Text |
        ConvertTo-SecureString

        $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecureString)
        [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
    }
}

要测试效果,请先使用这行代码:

PS> "Hello World" | ConvertTo-TextEncrypted | ConvertFrom-TextEncrypted
Hello World

下一步,得到相同的密文,然后将它保存到一个文件中:

$Path = "$env:temp\secret.txt"
'Hello World' | ConvertTo-TextEncrypted | Set-Content -Path $Path

现在,使用这行代码来读取加密的文件,然后对它进行解密:

$Path = "$env:temp\secret.txt"
Get-Content -Path $Path | ConvertFrom-TextEncrypted

请注意两个脚本都不包含密码。而实际的密码正是你的用户标识符。当另一个人,或是您在另一台机器上试图解开文件中的密文,将会失败。

这个方法可以用来安全地保存个人密码,这样您就不用每天都输入了。