VMware Cloud Community
vin01
Expert
Expert
Jump to solution

errors reported in wait-task

I am using below script to get service information from the windows guest os using invoke-vmscript but for few vms the credentials which i provided in the script are not valid so for those vms i am not getting any error output or vmname with blank result in output $report.

So is it possible to write the error output while using wait-task because when I look at the powershell console the wait-task is displaying the error 'Failed to authenticate with the guest operating system using the supplied credentials' but in the $task.Result.ScriptOutput is not showing up the  authentication failed error and even $task.Result.VM.Name is not showing up the vm name.

I am ok for few vms if authentication failed or any other error but expecting to write that error in $report for those vmnames.

$script = @'

$output=Get-Service |select Name

$output.Name -join ','

'@

$tasks = @()

foreach($singlevm in Get-VM test01,test02,test03,test04,test05,test06,test07){

    $sInvoke = @{

        VM            = $singlevm.Name

        GuestUser     = 'administrator'

        GuestPassword = 'password'

        ScriptText    = $script

        ScriptType    = 'Powershell'

        ErrorAction   = 'Stop'

    }

    $tasks+=Invoke-VMScript @sInvoke -RunAsync -Confirm:$false

}

Wait-Task -Task $tasks -Verbose

$report=foreach ($task in $tasks) {

'' | Select-Object @{N='VM';E={$task.Result.VM.Name}},

@{N ='Result'; E={$task.Result.ScriptOutput.Split("`n") |Where-Object { $_ -ne '' } | %{$_.Trim("`r`n")}}}

}

$report

pastedImage_2.png

Regards Vineeth.K
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

I had a typo in that last code.
It is corrected now.

And yes, you can bring it all together.

Something like this for example

$script = @'

$output=Get-Service |select Name

$output.Name -join ',' 

'@

$tasks = @()

foreach($singlevm in Get-VM 'Win2k16_Std_64bit-testClone'){

     $sInvoke = @{

        VM            = $singlevm

        GuestUser     = 'administrator'

        GuestPassword = 'password'

        ScriptText    = $script

        ScriptType    = 'Powershell'

        RunAsync = $true

        Confirm = $false

    }

    $tasks += @{

        VM = $singlevm

        Task = Invoke-VMScript @sInvoke

    }

}


while($tasks.Task.State -contains 'Running'){

    sleep 2

}


$tasks |

Select @{N='VM';E={$_.VM}},

    @{N='State';E={$_.Task.State}},

    @{N='Error';E={$_.Task.TerminatingError.Message}},

    @{N ='Result'; E={$_.Task.Result.ScriptOutput.Split("`n") |Where-Object { $_ -ne '' } | %{$_.Trim("`r`n")}}}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

17 Replies
LucD
Leadership
Leadership
Jump to solution

If you run the same but without RunAsync and the Wait-Task, do all these calls to Invoke-VMScript return correctly?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
vin01
Expert
Expert
Jump to solution

If I run like this nothing is captured in $tasks

$script = @'

$output=Get-Service |select Name

$output.Name -join ','

'@

$tasks = @()

foreach($singlevm in Get-VM 'Win2k16_Std_64bit-testClone'){

    $sInvoke = @{

        VM            = $singlevm.Name

        GuestUser     = 'administrator'

        GuestPassword = 'password'

        ScriptText    = $script

        ScriptType    = 'Powershell'

        ErrorAction   = 'Stop'

    }

    $tasks+=Invoke-VMScript @sInvoke

    #-RunAsync -Confirm:$false

}

pastedImage_1.png

Regards Vineeth.K
0 Kudos
LucD
Leadership
Leadership
Jump to solution

If you run without the RunAsync switch there is no Task returned by Invoke-VMScript.

But the result that you show seems to indicate that the supplied credentials are not correct for at least one of the targetted VMs.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
vin01
Expert
Expert
Jump to solution

If you run without the RunAsync switch there is no Task returned by Invoke-VMScript.

I just tested for one vm for which credentials are wrong. For that error is not written in $tasks. It’s just showed up in PowerShell console which I showed in above snap.

But the result that you show seems to indicate that the supplied credentials are not correct for at least one of the targetted VMs.

Yeah I intentionally give wrong credentials to show you.

Regards Vineeth.K
0 Kudos
LucD
Leadership
Leadership
Jump to solution

The error is not coming from the Guest OS on the target VM, but from the Invoke-VMScript cmdlet itself.

That explains why it is not in ScriptOutput.

The best way to catch incorrect credentials is to use a try-catch construct (I think we have discussed this before in some of your other threads).

That way you can intercept in the invalid credentials exception, report it and continue the script.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
vin01
Expert
Expert
Jump to solution

Yes LucD by using your last script I used try catch method now but its not giving any results.  How to use with -RunAsync switch and Wait-Task -Task $tasks because I need to run on large set of vms and with -RunAsync will give results more quicker.

$script = @'

$output=Get-Service |select Name

$output.Name -join ','

'@

$tasks = @()

foreach($singlevm in Get-VM 'Win2k16_Std_64bit-testClone'){

try {

    $sInvoke = @{

        VM            = $singlevm.Name

        GuestUser     = 'administrator'

        GuestPassword = 'password'

        ScriptText    = $script

        ScriptType    = 'Powershell'

        ErrorAction   = 'Stop'

    }

    $tasks+=Invoke-VMScript @sInvoke  -RunAsync -Confirm:$false

    break

    }

    catch {

    }

}

Wait-Task -Task $tasks -Verbose

$report=foreach ($task in $tasks) {

'' | Select-Object @{N='VM';E={$task.Result.VM.Name}},

@{N ='Result'; E={$task.Result.ScriptOutput.Split("`n") |Where-Object { $_ -ne '' } | %{$_.Trim("`r`n")}}}

}

$report

pastedImage_1.png

Regards Vineeth.K
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Ok, try-catch doesn't seem to work with a client-side task.

As an alternative I came up with the following.

It doesn't use the Wait-Task anymore, but uses a while-loop to wait till tasks have completed.

Then it splits out the ones in error and the ones that completed.

I used a hash table to keep track of the background tasks.

The reason is that a failed background task doesn't have the VM information anymore.

$script = @'

$output=Get-Service |select Name 

$output.Name -join ',' 

'@

$tasks = @()

foreach($singlevm in Get-VM 'Win2k16_Std_64bit-testClone'){

    $sInvoke = @{

        VM            = $singlevm

        GuestUser     = 'administrator'

        GuestPassword = 'password'

        ScriptText    = $script

        ScriptType    = 'Powershell'

        RunAsync = $true

        Confirm = $false

    }

    $tasks += @{

        VM = $singlevm

        Task = Invoke-VMScript @sInvoke

    }

}


while($tasks.Task.State -contains 'Running'){

    sleep 2

}


$tasks | where{$_.Task.State -eq 'Error'} |

ForEach-Object -Process {

    Write-Output "Call failed for $($_.VM) with error $($_.Task.TerminatingError.Message)"

}


$tasks | where{$_.Task.State -eq 'Success'} |

Select-Object @{N='VM';E={$_.Result.VM.Name}},

    @{N ='Result'; E={$_.Result.ScriptOutput.Split("`n") |Where-Object { $_ -ne '' } | %{$_.Trim("`r`n")}}}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

vin01
Expert
Expert
Jump to solution

Its not displaying any output for vms when authentication is success.

pastedImage_0.png

When authentication fails its writing the output.

pastedImage_1.png

I am also thinking instead of Write-Output can we keep it in one variable for both failure and success machines so that I can export to csv.

Regards Vineeth.K
0 Kudos
LucD
Leadership
Leadership
Jump to solution

I had a typo in that last code.
It is corrected now.

And yes, you can bring it all together.

Something like this for example

$script = @'

$output=Get-Service |select Name

$output.Name -join ',' 

'@

$tasks = @()

foreach($singlevm in Get-VM 'Win2k16_Std_64bit-testClone'){

     $sInvoke = @{

        VM            = $singlevm

        GuestUser     = 'administrator'

        GuestPassword = 'password'

        ScriptText    = $script

        ScriptType    = 'Powershell'

        RunAsync = $true

        Confirm = $false

    }

    $tasks += @{

        VM = $singlevm

        Task = Invoke-VMScript @sInvoke

    }

}


while($tasks.Task.State -contains 'Running'){

    sleep 2

}


$tasks |

Select @{N='VM';E={$_.VM}},

    @{N='State';E={$_.Task.State}},

    @{N='Error';E={$_.Task.TerminatingError.Message}},

    @{N ='Result'; E={$_.Task.Result.ScriptOutput.Split("`n") |Where-Object { $_ -ne '' } | %{$_.Trim("`r`n")}}}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

vin01
Expert
Expert
Jump to solution

Some issue. I am not getting the output. Below is the output.

pastedImage_0.png

For the same VM if I execute as below I can see the output.

pastedImage_0.png

Regards Vineeth.K
0 Kudos
LucD
Leadership
Leadership
Jump to solution

I think it is normal that there is nothing in Result when the State says 'error'


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
vin01
Expert
Expert
Jump to solution

But if I execute for that same VM as below I got the result.

Invoke-VMScript -VM $singlevm -ScriptText $script -ScriptType Powershell -GuestUser 'administrator' -GuestPassword ''

Regards Vineeth.K
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Then you probably need to check what is in $sInvoke.

I can't really debug that if it is something on your side.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Looks like the copy/paste had an error.

The Invoke-VMScript was called twice. I corrected that

I just did some more testing with 2 targets, one with a correct password and one with an incorrect password.

And the result is what I expected.

task.jpg


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

vin01
Expert
Expert
Jump to solution

Yes Thanks now its  working with this version,

One last question for this thread Is it possible to capture failed and success output using wait-task because based on your last reply for my other thread(Same output is displayed multiple times ) I have created the script which I posed as question in this thread. Why I am wait-task is because the execution is very fast.

Regards Vineeth.K
0 Kudos
LucD
Leadership
Leadership
Jump to solution

No, that's why I used the While-loop instead of Wait-Task.

Wait-Task shows the error and nothing else.

With the While-loop I can check the State of the Task.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

vin01
Expert
Expert
Jump to solution

Ok Thanks

Regards Vineeth.K
0 Kudos