Rob*_*Ppl 6 variables parameters powershell scripting active-directory
我正在学习 PowerShell 为我的团队编写工具。我今天很忙,但我想通过删除 ForEach 循环中的 IF 语句来简化它,因为命令之间的唯一区别是参数-replace或-remove。
Write-Host "This script removes or replaces en masse users' msds-SyncServerURL property"
DO {
$TargetSSU=Read-Host "`nWhat msds-SyncServerURL do you want to replace or remove?"
$UsersToBeFixed=Get-ADUser -Filter {msds-SyncServerURL -like $TargetSSU} -Properties ('name','samaccountname','msDS-SyncServerURL')
IF ($UsersToBeFixed -eq $null) {
Write-Host "`nNo users appear to have $TargetSSU as their msds-SyncServerURL value. Please try again."
}
} UNTIL ($UsersToBeFixed -ne $null)
Write-Host "`n`nThe following users have $TargetSSU as their msds-SyncServerURL value:"
$UsersToBeFixed |select name,samaccountname,msds-syncserverurl|ft
DO {
$Action=Read-Host "Do you want to [R]emove or [U]pdate $TargetSSU?"
} Until (($Action -eq "R") -or ($Action -eq "U"))
IF ($Action -eq "U") {
DO {
$NewSyncServer=Read-Host "`nEnter the new Sync Server's hostname (not the URL)"
Write-Host "`nChecking to see if $NewSyncServer has a userfile share..."
$VerifySyncServer=Test-Path \\$NewSyncServer\userfiles
IF ($VerifySyncServer -eq $false) {
Write-host "`n$NewSyncServer does not appear to be a valid Sync Server hostname. Please try again."
}
} UNTIL ($VerifySyncServer -eq $true)
$TargetSSU="https://$NewSyncServer.ourdomain.com"
}
ForEach ($userToBeFixed in $UsersToBeFixed) {
Write-Host "`nFixing" ($usertobefixed).name
IF ($Action -eq "R") {
Set-ADObject -identity $userToBeFixed -remove @{"msDS-SyncServerUrl" = $TargetSSU}
}
IF ($Action -eq "U") {
Set-ADObject -identity $userToBeFixed -replace @{"msDS-SyncServerUrl" = $TargetSSU}
}
}
Write-Host "`nHere is the result of the operation:"
foreach ($userToBeFixed in $UsersToBeFixed) {
Get-ADUser -Identity $userToBeFixed -Properties ('name','samaccountname','msDS-SyncServerURL')|select name,samaccountname,msds-syncserverurl
}
Run Code Online (Sandbox Code Playgroud)
我最初有以下开关,尝试各种引号排列,甚至 {$action="replace"}:
Switch($action)
{
R {'remove'}
U {'replace'}
}
Run Code Online (Sandbox Code Playgroud)
我还在 ForEach 循环中尝试了 Invoke-Expression:
$CMD="Set-ADObject -identity $userToBeFixed -$action @{`"msDS-SyncServerUrl`" = $TargetSSU}"
Invoke-Expression -Command $CMD
Run Code Online (Sandbox Code Playgroud)
Set-ADObject cmdlet总是会失败,通常会抱怨 Set-ADObject 无法找到接受“-remove”、“System.Object[]”或“System.Collections.Hashtable”等参数的位置参数。
我将问题与 Set-ADObject 隔离,不喜欢将$action变量用作参数。如果我用-replace或-remove替换-$action它将起作用(就像在上面的代码片段中一样)。
我意识到这是一个小问题,但似乎没有理由拥有如此冗余的代码让我感到困扰。我很想学习如何解决这个问题。
另外,无关,我还没有找到更好的方法来做到这一点:
Until (($Action -eq "R") -or ($Action -eq "U"))
Run Code Online (Sandbox Code Playgroud)
我已经搜索并尝试了其他解决方案,例如:
Until ($Action -eq @{"R" -or "U"})
Run Code Online (Sandbox Code Playgroud)
但是好像不能综合多个条件的评价。这让我很困扰,但不像我在这里的主要问题那么困扰。
请放过我吧。我对这件事很陌生。如果有人看到我可以改进的其他内容,请告诉我。我想学这个。
谢谢。
你可以用splatting来解决这个问题。
例如:
$action = 'Recurse'
$params = @{ $action = $true }
Get-ChildItem @params
Run Code Online (Sandbox Code Playgroud)
该示例在功能上等同于Get-ChildItem -Recurse