2016-02-08 2 views
1

Я работаю над методом обработки ошибок для своих сценариев PowerShell. Я передаю ему ошибку через try/catch на catch, но я хочу выполнить итерацию исходных параметров из командной строки, которая вызвала ее, чтобы создать журнал ошибок и сообщение об ошибке.

Вот что я до сих пор:

# --params-- 
param(
    [string]$Directory, 
    [string]$ArchiveDirectory, 
    [string]$ErrorDirectory, 
    [string]$ErrorEmailFrom, 
    [string]$ErrorEmailTo, 
    [string]$ErrorEmailSubject, 
    [string]$ErrorSMTP, 
    [string]$FTPSite, 
    [string]$FTPUser, 
    [string]$FTPPass, 
    [string]$FTPRemoteDir 
) 

# list of arguments for debug 
$paramList = $args 

# --functions-- 

function Handle-MyError 
{ 
    Write-Host "handle-error" 
    Write-Host $args[0]; # this is the exception passed in 

    # -Email alert- 
    $subject = $ErrorEmailSubject + $FTPSite 
    # build message 
    $message = Get-Date -Format "yyyy-mm-dd hh:mm:ss" 
    $message += "`r`nError: " + $FTPSite + " : " + $args[0] 
    $message += "`r`nParameters:`r`n" 

    # Grab each parameter value, using Get-Variable 
    for ($i=0;$i -lt $paramList.Length; $i++) 
    { 
    $message += $paramList[$i] 
    } 

    # send email 
    $smtp = New-Object Net.Mail.SmtpClient($ErrorSMTP) 
    $smtp.Send($ErrorEmailFrom, $ErrorEmailTo, $subject, $message) 

    # drop error file 
    $theDate = Get-Date -Format "yyyymmdd" 
    $errorFile = $ErrorDirectory + "\" + $theDate + "_ERROR.txt" 
    Write-Host $errorFile 
    $message | Out-File $errorFile -Append 
} 

и в моем try/catch:

catch [Exception] 
{ 
    Write-Host "SPOT 1" 
    Handle-MyError $_. 
} 

На вершине, я стараюсь, чтобы сохранить оригинальный $args как $paramList перебрать позже, но он не работает. Внутри метода Handle-MyError, $args становится ошибкой, которая передается, поэтому я подумал, что если я сохраню оригинал $args как $paramList, я мог бы получить к нему доступ позже, но он вон ... Идеи?

ответ

3

Есть несколько способов, чтобы худшего к лучшему:

Использование Get-Variable с Scope параметром. номер Комплект может отличаться, но оно должно быть по крайней мере 2 (Script->Catch->Handle-MyError)

function Handle-MyError 
{ 
    Write-Host (Get-Variable -Name ErrorEmailFrom -ValueOnly -Scope 2) 
} 

Используя $Script: префикс

function Handle-MyError 
{ 
    Write-Host $Script:ErrorEmailFrom 
} 

Использование $PSBoundParameters

# list of arguments for debug 
$paramList = $PsBoundParameters 

function Handle-MyError 
{ 
    Param 
    (
     $Exception, 
     $Cfg 
    ) 

    Write-Host $Cfg.ErrorEmailFrom 
} 

catch [Exception] 
{ 
    Write-host "SPOT 1" 
    Handle-MyError -Exception $_ -Cfg $paramList 
} 

Использование splatting:

$paramList = $PsBoundParameters 

function Handle-MyError 
{ 
    Param 
    (
     $Exception, 
     $ErrorDirectory, 
     $ErrorEmailFrom, 
     $ErrorEmailTo, 
     $ErrorEmailSubject, 
     $ErrorSMTP 
    ) 

    Write-Host $ErrorEmailFrom 
} 

catch [Exception] 
{ 
    Write-host "SPOT 1" 
    Handle-MyError @paramList -Exception $_ 
} 
+0

$ PsBoundParameters не будет работа, если это не метод внутри файла, правильно? Я проверил $ ​​PsBoundParameters, но он ничего не содержит. Кроме того, когда я прохожу через несвязанные параметры, я буквально получаю каждое слово в одном из параметров как отдельные значения ... довольно странно –

+0

В идеале, я хотел бы иметь один многоразовый «foreach», который я могу использовать во всех своих сценариях PS для прокрутки и выгрузки всех значений параметров в сообщение электронной почты об ошибке для отладки porpuses. –

+0

@Beau Не уверен, что вы подразумеваете под «методом внутри файла». Пока у вас есть оператор 'Param',' $ PSBoundParameters' должен быть заполнен всеми переданными параметрами. Вы не можете получить доступ к '$ PSBoundParameters' в отладчике, однако вы должны назначить его другому var. заранее в коде и вместо этого перечислите эту переменную. '$ paramList' в примерах должен делать трюк. – beatcracker

0

Вот мой последний код после некоторой помощи от @beatcracker. Я объединил две части головоломки.

  1. Мне нужно, чтобы сохранить первоначальный Params в локальном варе и два, ($paramList = $PsBoundParameters)
  2. Доступ к этой вар/список с помощью .GetEnumerator()

    # --params-- 
    param(
        [string]$Directory, 
        [string]$ArchiveDirectory, 
        [string]$ErrorDirectory, 
        [string]$ErrorEmailFrom, 
        [string]$ErrorEmailTo, 
        [string]$ErrorEmailSubject, 
        [string]$ErrorSMTP, 
        [string]$FTPSite, 
        [string]$FTPUser, 
        [string]$FTPPass, 
        [string]$FTPRemoteDir 
    ) 
    # set params as var for debug later 
    $paramList = $PsBoundParameters 
    
    # --functions-- 
    
    function Handle-MyError 
    { 
        Write-Host "handle-error" 
        #write-host "Exception:" $args[0]; # this is the exception passed in 
    
        # -Email alert- 
    
        # build subject 
        $subject = $ErrorEmailSubject + " " + $FTPSite 
    
        # build message 
        $message = Get-Date -format s 
        $message += "`r`nError Message: " + $args[0] 
        $message += "`r`nParameters:`r`n" 
    
        $paramList.GetEnumerator() | ForEach-Object ` 
        { 
         #Write-Host $_.Key "=" $_.Value 
         if ($_.Key -ne "FTPPass"){ 
          $message += "`r`n" + $_ 
         } 
        } 
    }