我在企业环境中工作,管理着一个拥有 75 台计算机的实验室。我使用 Ghost 进行映像处理,然后检查计算机以更改 PC 名称和 SID。
我正在实现一个脚本来自动将计算机添加到域中,但我对 PowerShell 还不熟悉,非常感谢您的帮助。这是我正在使用的脚本 1.ps1:
Param (
[String]$User = $(Throw "MYDOMAINUSERINFO"),
[String]$Domain = "MYDOMAININFO",
[String]$PathToCred = "C:\OMC\AutoPost"
)
#Make sure our path string has a trailing backslash
If ($PathToCred[$PathToCred.Length - 1] -ne "\")
{ $PathToCred += "\"
}
#Now create file string
$File = $PathToCred + "JoinDomain-$User.crd"
#And find out if it's there, if not create it
If (-not (Test-Path $File))
{ (Get-Credential).Password | ConvertFrom-SecureString | Set-Content $File
}
#Load the credential file
$Password = Get-Content $File | ConvertTo-SecureString
$Credential = New-Object System.Management.Automation.PsCredential($User,$Password)
#Add the computer to the domain
Add-Computer -DomainName $Domain -Credential $Credential
我使用放置在启动文件夹中的批处理文件运行该脚本。
Powershell.exe -ExecutionPolicy Bypass C:\OMC\AutoPost\1.ps1 -User MYDOMAINUSERINFO -Domain MYDOMAININFO -PathToCred C:\OMC\AutoPost\
运行此脚本可以正常工作,它会创建一个凭据文件,读取凭据文件并加入域。在 ghosting 和 walking 之后运行此脚本不起作用,我收到错误:
Key not valid for use in specified state.
我认为这是因为计算机知道某些东西已经发生了变化。我使用与最初构建凭据时相同的用户帐户添加到域,因此我相信计算机拒绝这些凭据是因为 SID 已更改。
我在网上看到我可以使用 [-key Byte[]] 设置标准加密密钥,这样我就可以避免这个错误。我对 PowerShell 还不太熟悉,不知道如何使用它,有人能帮我吗?
More info:
https://technet.microsoft.com/en-us/library/hh849814.aspx
http://ss64.com/ps/convertfrom-securestring.html
Stack Overflow 问题 - https://stackoverflow.com/questions/32258829/powershell-secure-string-encryption-key-usage-join-domain-script
答案1
将以下内容粘贴到脚本中。我将其命名为“Custom-ZTIDomainJoin.ps1”
我将其放入 %SCRIPTROOT%
[CmdletBinding()]
Param(
[参数(强制 = $True)] $域,
[Parameter(Mandatory=$True)]
$UserName,
[Parameter(Mandatory=$True)]
$Password,
[Parameter(Mandatory=$False)]
$OU,
[Parameter(Mandatory=$False)]
[Switch]$Log
)
清除屏幕
Clear-Host
定义默认操作首选项
$DebugPreference = "Continue"
$ErrorActionPreference = "Continue"
$WarningPreference = "Continue"
定义 ASCII 字符
$Equals = [char]61
$Space = [char]32
$SingleQuote = [char]39
$DoubleQuote = [char]34
$NewLine = "`n"
设置工作目录
$ScriptDir = $MyInvocation.MyCommand.Definition | Split-Path -Parent
$ScriptName = [System.IO.Path]::GetFileNameWithoutExtension($MyInvocation.MyCommand.Name)
$Temp = "$Env:LocalAppData\Temp"
如果存在“/Log”开关,则开始记录脚本输出
If ($Log.IsPresent) {(Start-Transcript -Path "$Temp\$ScriptName.log")}
查询 WMI
$HostName = (Get-WmiObject -Class Win32_ComputerSystem -Property Name | Select -ExpandProperty Name).Trim().ToUpper()
$OSArchitecture = (Get-WmiObject -Class Win32_OperatingSystem -Property OSArchitecture | Select -ExpandProperty OSArchitecture).Replace("-bit", "").Replace("32", "86").Insert(0,"x").ToUpper()
$OSVersion_Major = ([Environment]::OSVersion.Version.Major)
$OSVersion_Minor = ([Environment]::OSVersion.Version.Minor)
[Decimal]$OSVersion = ("$OSVersion_Major" + "." + "$OSVersion_Minor")
定义函数
#Encode a plain text string to a Base64 string
Function ConvertTo-Base64 ($String)
{
$Encoded = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($String))
Return $Encoded
}
#Decode an Base64 string to a plain text string
Function ConvertFrom-Base64 ($String)
{
$Decoded = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($String))
Return $Decoded
}
如果脚本正在 Microsoft 部署工具包任务序列中运行,请执行以下步骤
If (Test-Path -Path TSEnv: -ErrorAction SilentlyContinue)
{
If ($OSVersion -lt "10.0")
{
#MDT passes in sensitive values as Base64 encoded strings, so they MUST be decoded to plain text first
$Domain = ConvertFrom-Base64 -String "$Domain"
$UserName = ConvertFrom-Base64 -String "$UserName"
$Password = ConvertFrom-Base64 -String "$Password" | ConvertTo-SecureString -AsPlainText -Force
$OU = $TSEnv:MachineObjectOU
#Create Credential Object For Active Directory Operations
$Credentials = (New-Object System.Management.Automation.PSCredential("$Domain\$UserName", $Password))
#Join the specified Active Directory Domain
$Device_JoinDomain = (Add-Computer -DomainName $Domain -Credential $Credentials -Force -Verbose)
#Wait 15 Seconds
(Start-Sleep -Seconds "15")
}
ElseIf ($OSVersion -ge "10.0")
{
#MDT passes in sensitive values as Base64 encoded strings, so they MUST be decoded to plain text first
$Password = (ConvertTo-SecureString -String "$Password" -AsPlainText -Force)
$OU = $TSEnv:MachineObjectOU
#Create Credential Object For Active Directory Operations
$Credentials = (New-Object System.Management.Automation.PSCredential("$Domain\$UserName", $Password))
#Join the specified Active Directory Domain
$Device_JoinDomain = (Add-Computer -DomainName $Domain -Credential $Credentials -Force -Verbose)
#Wait 15 Seconds
(Start-Sleep -Seconds "15")
}
}
如果脚本未在 Microsoft 部署工具包任务序列中运行,请执行以下步骤
ElseIf (!(Test-Path -Path TSEnv: -ErrorAction SilentlyContinue))
{
#Convert the password to a Secure String
$Password = (ConvertTo-SecureString -String "$Password" -AsPlainText -Force)
#Create Credential Object For Active Directory Operations
$Credentials = (New-Object System.Management.Automation.PSCredential("$Domain\$UserName", $Password))
#Join the specified Active Directory Domain
$Device_JoinDomain = (Add-Computer -DomainName $Domain -Credential $Credentials -Force -Verbose)
#Wait 15 Seconds
(Start-Sleep -Seconds "15")
}
如果存在“/Log”开关,则停止记录脚本输出
Get-Variable | Out-GridView -Title“从 $ScriptName.ps1 收集的变量”-Wait
如果 ($Log.IsPresent) {(Stop-Transcript)}