Пропустить часть скрипта при ошибке - PullRequest
0 голосов
/ 29 июня 2018

Я долго бился головой об стену на этом. Никакое количество Google не дало мне никаких успешных результатов. Хотите знать, если кто-то может дать мне руку?

# 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: Этот сценарий находит группу компьютеров в назначенной группе, переименовывает их, а затем удаляет их из группы. Мне нужна помощь, чтобы сказать сценарию НЕ удалять их из группы в случае сбоя переименования (компьютер отключен и т. Д.) Или выдает какую-то ошибку.

Мысли

Заранее спасибо!

1 Ответ

0 голосов
/ 29 июня 2018

Есть несколько способов проверить результат выполнения командлета в Powershell.

Запустите командлет как условие if

Вы можете использовать возвращенный объект командлета в качестве условия оператора 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
}

$? оценивает успешность последнего запуска командлета (не путайте это с $LASTEXITCODE, который предназначен для проверки результата программы последнего запуска, а не результата командлета). Если командлет выполнен успешно, он возвращает $True, если нет, $False.

Перехват ошибок в Try/Catch блоке

Третий способ сделать это - использовать блок try/catch, хотя вы должны убедиться, что любая ошибка завершается (остановит скрипт, если он не обнаружен), чтобы перехватить исключение. Для этого вы можете использовать -ErrorAction Stop paremeter:

    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, и вам не нужно указывать его в каждом командлете .

Дополнительная информация

Вот несколько официальных документов о try/catch/finally и if заявлениях в Powershell. Я не охватывал finally выше, но это необязательная часть try/catch операторов:

Об If : https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_if?view=powershell-6

О Try / Catch / Наконец : https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_try_catch_finally?view=powershell-6

Здесь также приведена дополнительная информация об исключениях, ошибках и их обработке в Powershell : https://kevinmarquette.github.io/2017-04-10-Powershell-exceptions-everything-you-ever-wanted-to-know/

...