4

I have a small script that copies files to a list of remote machines. In this script I use:

Copy-Item "$AppLocation\$AppName" -destination "\\$MachineName\c$\" -force

This can throw various types of errors. If this throws an error, I want to log the error to a file and then continue. My question is that I'd like to know what would be the right way to find out if the Copy-Item command was successful.

Next question is related:

psexec \\$MachineName -u $RemoteLogin -p $Remotepassword -s -i -d C:\$AppName

What would be a good way to find out how this command executed? I get a message in the console that it exited with 0 but I have no idea how I could get the return code into a local variable.

I can also use this:
(Get-WMIObject -ComputerName $MachineName -List | Where-Object -FilterScript {$_.Name -eq "Win32_Product"}).Install("C:\$AppName","","false")
which works fine, but still, no idea how to find out if it succeeded unless I read the output.

Thanks!

flayn
  • 5,272
  • 4
  • 48
  • 69

4 Answers4

2

Use Try and catch as follow

$ErrorActionPreference='Stop'
Try{
Write-Host "Finished OK"
}
Catch [system.exception]
{
    Write-Host "Finished with Error"
    Write-Host $_.Exception.ToString()
    exit -1
}
Eddietec
  • 351
  • 2
  • 4
2

Concerning the first part of your question, you can use

Copy-Item ... -ErrorAction Continue -ErrorVariable yourVariable

Error action tells the cmdlet what to do if case of error , ErrorVariable will put any error in the variable of your choice ($yourVariable in the exemple).

$? automatic variable contains the execution status of the last operation. If it's false, just check the content of $yourVariable to know what went wrong and do whatever you want with it (like write it in a file in your case).

You can also use

Copy-Item ... -ErrorAction Continue 2> [pathToLogFile]

This will redirect the error stream of the cmdlet to a file of your choice...

Concerning the second part of your question : $LASTEXITCODE contains the return code of your last executable.

Have you considered using the remoting capabilities of Powershell 2 for more control ?

Hope it helps

Cédric

Cédric Rup
  • 15,468
  • 3
  • 39
  • 30
  • 1
    Brilliant! Thanks a lot. Using the powers of google I found out more about the ErrorVariable, and now I am using it like this: $err=@() Copy-Item ... -ErrorAction Continue -ErrorVariable +err This works really well. – flayn Dec 04 '09 at 13:53
  • 1
    If think you don't need to initialize the variable before using it this that. Consider reading about common parameters, automatic variables and specific variables like $ErrorActionPreference : this will help you a lot – Cédric Rup Dec 04 '09 at 14:29
1

There's a lot to your questions.

Here's something I've done to read results from console apps like psexec:

    [System.Diagnostics.ProcessStartInfo]$info = New-Object System.Diagnostics.ProcessStartInfo
    $info.WorkingDirectory = "C:\"
    $info.UseShellExecute = $false
    $info.RedirectStandardOutput = $true 
    $info.CreateNoWindow = $true
    [System.Diagnostics.Process]$proc = [System.Diagnostics.Process]::Start($info)

    if (($proc -ne $null) -and ($proc.id -ne 0)) { [void]$proc.WaitForExit($timeOutMs); }
    $proc.StandardOutput.ReadToEnd();

Note, that that's untested code, but it came from something that works and I just did a little editing for simplicity.

Now, you can process the text output of psexec and handle accordingly.

Kevin Buchan
  • 2,790
  • 3
  • 27
  • 34
0

I use a powershell script to delete old files. This outputs a message to the screen, which could just as easily write a message to the event log. Details here.

Writing to the event log can be done with the Write-EventLog command. Good details about that on MSDN and TechNet. Loads of information comes up in the search engines for this too.

Mark Cooper
  • 6,738
  • 5
  • 54
  • 92