【问题标题】:Logging actual error when script fails脚本失败时记录实际错误
【发布时间】:2015-09-01 21:12:07
【问题描述】:

我这里有一个脚本,可以读取计算机列表并更改管理员密码。当脚本运行时,它会有一个日志文件说明任务是成功还是失败。但我也想在失败时将实际错误记录到日志中。我该如何做到这一点?

[cmdletbinding()]
param (
[parameter(mandatory = $true)]
$InputFile,
$OutputDirectory
)

if(!$outputdirectory) {
    $outputdirectory = (Get-Item $InputFile).directoryname
}   
$failedcomputers    =   Join-Path $outputdirectory "output.txt"
$stream = [System.IO.StreamWriter] $failedcomputers
$stream.writeline("ComputerName `t IsOnline `t PasswordChangeStatus")
$stream.writeline("____________ `t ________ `t ____________________")

$password = Read-Host "Enter the password" -AsSecureString
$confirmpassword = Read-Host "Confirm the password" -AsSecureString

$pwd1_text = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($password))
$pwd2_text = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($confirmpassword))

if($pwd1_text -ne $pwd2_text) {
    Write-Error "Entered passwords are not same. Script is exiting"
    exit
}

if(!(Test-Path $InputFile)) {
    Write-Error "File ($InputFile) not found. Script is exiting"
    exit
}

$Computers = Get-Content -Path $InputFile

foreach ($Computer in $Computers) {
    $Computer   =   $Computer.toupper()
    $Isonline   =   "OFFLINE"
    $Status     =   "SUCCESS"
    Write-Verbose "Working on $Computer"
    if((Test-Connection -ComputerName $Computer -count 1 -ErrorAction 0)) {
        $Isonline = "ONLINE"
        Write-Verbose "`t$Computer is Online"
    } else { Write-Verbose "`t$Computer is OFFLINE" }

    try {
        $account = [ADSI]("WinNT://$Computer/username,user")
        $account.psbase.invoke("setpassword",$pwd1_text)
        Write-Verbose "`tPassword Change completed successfully"
    }
    catch {
        $status = "FAILED"
        Write-Verbose "`tFailed to Change the administrator password. Error: $_"
    }

    $obj = New-Object -TypeName PSObject -Property @{
        ComputerName = $Computer
        IsOnline = $Isonline
        PasswordChangeStatus = $Status
    }

    $obj | Select ComputerName, IsOnline, PasswordChangeStatus

    if($Status -eq "FAILED" -or $Isonline -eq "OFFLINE") {
        $stream.writeline("$Computer `t $isonline `t $status")
    }

}
$stream.close()
Write-Host "`n`nFailed computers list is saved to $failedcomputers"

【问题讨论】:

    标签: powershell error-logging


    【解决方案1】:

    改变这个:

    catch {
        $status = "FAILED"
        Write-Verbose "`tFailed to Change the administrator password. Error: $_"
    }
    

    到这里:

    catch {
        $status = "FAILED"
        Write-Verbose "`tFailed to Change the administrator password. Error: $_"
        $errmsg = $_.Exception.Message
    }

    保留错误消息。并改变这个:

    if($Status -eq "FAILED" -or $Isonline -eq "OFFLINE") {
        $stream.writeline("$Computer `t $isonline `t $status")
    }
    

    到这里:

    if($Status -eq "FAILED" -or $Isonline -eq "OFFLINE") {
        $stream.writeline("$Computer `t $isonline `t $status `t $errmsg")
    }

    在日志中包含错误消息。


    如果你也想展开内部异常,你可以使用这个:

    $e = $_.Exception
    $errmsg = $e.Message
    while ($e.InnerException) {
      $e = $e.InnerException
      $errmsg = "`n" + $e.Message
    }
    

    而不仅仅是

    $errmsg = $_.Exception.Message
    

    【讨论】:

    • 嗨@Ansgar Wiechers,谢谢你的回答!如果假设我想记录每一个失败和成功,我是做一个 if else 语句还是我可以写 if($Status -eq "FAILED" -or "SUCCESS" -or $Isonline -eq "OFFLINE" -or "ONLINE ") {
    • 您不想为 SUCCESS 记录错误消息,因此您应该使用ifswitch 控制结构来区分日志消息。
    猜你喜欢
    • 2021-06-03
    • 2013-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-08
    相关资源
    最近更新 更多