脚本失败时记录实际错误
Logging actual error when script fails
我这里有一个脚本可以读取计算机列表并更改管理员密码。当脚本为 运行 时,它将有一个日志文件,说明任务是成功还是失败。但我也想在失败时将实际错误记录到日志中。我该如何实现?
[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"
改变这个:
catch {
$status = "FAILED"
Write-Verbose "`tFailed to Change the administrator password. Error: $_"
}
对此:
catch {
$status = "FAILED"
Write-Verbose "`tFailed to Change the administrator password. Error: $_"
<b>$errmsg = $_.Exception.Message</b>
}
保留错误信息。并更改此:
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 <b>`t $errmsg</b>")
}
在日志中包含错误消息。
如果你也想展开内部异常,你可以使用这个:
$e = $_.Exception
$errmsg = $e.Message
while ($e.InnerException) {
$e = $e.InnerException
$errmsg = "`n" + $e.Message
}
而不仅仅是
$errmsg = $_.Exception.Message
我这里有一个脚本可以读取计算机列表并更改管理员密码。当脚本为 运行 时,它将有一个日志文件,说明任务是成功还是失败。但我也想在失败时将实际错误记录到日志中。我该如何实现?
[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"
改变这个:
catch {
$status = "FAILED"
Write-Verbose "`tFailed to Change the administrator password. Error: $_"
}
对此:
catch {
$status = "FAILED"
Write-Verbose "`tFailed to Change the administrator password. Error: $_"
<b>$errmsg = $_.Exception.Message</b>
}
保留错误信息。并更改此:
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 <b>`t $errmsg</b>")
}
在日志中包含错误消息。
如果你也想展开内部异常,你可以使用这个:
$e = $_.Exception
$errmsg = $e.Message
while ($e.InnerException) {
$e = $e.InnerException
$errmsg = "`n" + $e.Message
}
而不仅仅是
$errmsg = $_.Exception.Message