在这上面我已经将头撞墙了一段时间了。迄今为止,没有多少谷歌搜索为我带来任何成功的结果。想知道有人可以帮我吗?
# Load the PowerShell module for Active Directory
Import-Module ActiveDirectory
# For each computer in AD that is a member of the target group
Get-ADGroupMember -Identity "CN=RenameComputer,CN=Users,DC=int,DC=example,DC=com" | ForEach {
# Define the new name as the old one, minus one letter at the end
$NewComputerName = $_.Name -replace ".$"
# Perform the rename operation
Rename-Computer -ComputerName $_.Name -NewName $NewComputerName -Force -PassThru -Restart -WhatIf
# Remove the computer from the target group
# THIS SHOULD NOT OCCUR IF THE RENAME ABOVE FAILED!!!
Remove-ADGroupMember -Identity "CN=RenameComputer,CN=Users,DC=int,DC=example,DC=com" -Members $NewComputerName -WhatIf
}
TL; DR::该脚本在指定组中查找一堆计算机,对其进行重命名,然后将其从该组中删除。我需要帮助告诉脚本在重命名失败(计算机处于脱机状态等)或引发某些错误的情况下,不要将其从组中删除。
有想法吗?
谢谢!
答案 0 :(得分:5)
有几种方法可以在Powershell中检查cmdlet的结果。
if
语句条件运行您可以将cmdlet的返回对象用作if
语句条件,只要它在成功时返回一个对象(这就是为什么我们需要-PassThru
用于Rename-Computer
的原因,通常不会返回任何对象)。因此,以您的代码为例(并删除-WhatIf
):
# If Rename-Computer succeeds...
if( Rename-Computer -ComputerName $_.Name `
-NewName $NewComputerName -Force -PassThru -Restart ) {
# then remove the Computer from group
Remove-ADGroupMember -Identity "CN=RenameComputer,CN=Users,DC=int,DC=example,DC=com" `
-Members $NewComputerName
}
之所以可行,是因为对象在Powershell中是真实的。大多数定义的对象和0
(零)以外的任何数字都被认为是$True
,但是诸如$null
,""
(空字符串)和0
之类的值(零)被评估为$False
。因此,对于您的代码,如果成功,将返回一个对象($True
),如果发生错误,将不返回任何对象($ False)。
或者,您可以先运行Rename-Computer
,然后检查其成功:
Rename-Computer -ComputerName $_.Name -NewName $NewComputerName -Force
# Check success of last cmdlet
if( $? ) {
Remove-ADGroupMember -Identity "CN=RenameComputer,CN=Users,DC=int,DC=example,DC=com" `
-Members $NewComputerName
}
$?
评估上一次cmdlet运行的成功(不要将此与$LASTEXITCODE
混淆,后者用于检查上次运行的程序结果,而不是cmdlet结果)。如果该cmdlet成功,则返回$True
,否则返回$False
。
Try/Catch
块中捕获错误第三种方法是使用try/catch
块,尽管您必须确保终止任何错误(如果未被捕获,则将停止脚本)以捕获异常。您可以为此使用-ErrorAction Stop
参数:
try {
Rename-Computer -ComputerName $_.Name -NewName $NewComputerName -Force `
-PassThru -Restart -ErrorAction Stop
Remove-ADGroupMember -Identity "CN=RenameComputer,CN=Users,DC=int,DC=example,DC=com" `
-Members $NewComputerName
} catch {
# Do something on failure
Write-Warning "An error occurred: $($_.Exception.Message)"
}
如果Rename-Computer
在try
块内引发错误(错误将失败),则执行将跳至catch
块,并跳过Remove-ADGroupMember
。如果使用try/catch
是首选的错误处理方法,则可以考虑在脚本中设置$ErrorActionPreference = 'Stop'
,这会将默认的-ErrorAction
行为设置为Stop
,而您没有不必在每个cmdlet上都指定它。
以下是有关Powershell中try/catch/finally
和if
语句的一些官方文档。我没有在上面介绍finally
,但这是try/catch
语句的可选部分:
以下是有关异常,错误以及在Powershell中处理它们的一些高级信息:https://kevinmarquette.github.io/2017-04-10-Powershell-exceptions-everything-you-ever-wanted-to-know/