VMware Cloud Community
ganapa2000
Hot Shot
Hot Shot
Jump to solution

Unable to get output from remote VMs

Hi,

I am unable to get output from remote VMs using below script. There is no errors.

Please help

Script

$reportlocation2 = "D:\reports\Shared_OS_Info1.csv"

$reportlocation = "D:\reports\Shared_Patching_Info.xlsx"

$Today = (Get-Date)

$StartDate = $Today.Date.AddDays(-10)

$EndDate = $Today.Date.AddDays(1)

Import-Csv -Path $reportlocation2 -UseCulture -PipelineVariable row |

ForEach-Object -Process {

    try{

        $patchcount = Invoke-Command -ComputerName $_.Name -ScriptBlock {(Get-HotFix | Where {$_.InstalledOn -gt $using:StartDate -AND $_.InstalledOn -lt $using:EndDate }).count}

    }

        catch

    {

        $patchcount = 'NA'

    }

        $row | Add-Member -MemberType NoteProperty -Name 'Patch_Count' -Value $patchcount -PassThru

} | Export-Excel -Path $reportlocation

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

You could do something like this

$report1 = @()

$report2 = @()


Import-Csv -Path $reportlocation1 -UseCulture -PipelineVariable row |

ForEach-Object -Process {

    $sInvoke = @{

        VM              = $row.VmName

        GuestCredential = $cred

        ScriptTYpe      = 'powershell'

        ScriptText      = $code

    }

    $dummy, $out1, $out2 = (Invoke-VMScript @sInvoke).ScriptOutput -split '### Output ###'

    $out1 = $out1.TrimStart("`n`r") -split "`n`r"

    $out2 = $out2.TrimStart("`n`r")


    $report1 += $out1 | ConvertFrom-Csv -UseCulture | Select-Object -Property CSName, HotFixID, Description, Caption, InstalledOn, InstalledBy

    $report2 += New-Object -TypeName PSObject -Property ([ordered]@{

        VM    = $row.VmName

        Count = [int]$out2

    })

}


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

View solution in original post

0 Kudos
10 Replies
LucD
Leadership
Leadership
Jump to solution

Is there a reason you are using Invoke-Command instead of Invoke-VMScript?

Don't these VM all have VMware Tools installed?

There are requirements to run remote commands, see about_Remote_Requirements.

Are these all met?

As a first step, add the Verbose switch on the Invoke-Command.


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

0 Kudos
ganapa2000
Hot Shot
Hot Shot
Jump to solution

Hi LucD,

I tried using Invoke-VMscript as you mentioned, but it I am not getting any output captured from Invoke-VMScript variable

$reportlocation2 = "D:\reports\OS_Info.csv"

$reportlocation = "D:\Patching_Info_$date.xlsx"

$Today = (Get-Date)

$StartDate = $Today.Date.AddDays(-10)

$EndDate = $Today.Date.AddDays(1)

Import-Csv -Path $reportlocation2 -UseCulture -PipelineVariable row |

ForEach-Object -Process {

    try{

         $patchcount = Invoke-VMScript -vm $_.Name -ScriptText "(Get-HotFix | Where {$_.InstalledOn -gt $using:StartDate -AND $_.InstalledOn -lt $using:EndDate }| Measure-Object).Count" -ScriptType PowerShell -GuestUser "abc\admin" -GuestPassword "password@123"

    }

        catch

    {

        $patchcount = 'NA'

    }

        $row | Add-Member -MemberType NoteProperty -Name 'Patch_Count' -Value $patchcount -PassThru

} | Export-Excel -Path $reportlocation

If I use direct command as below, I am getting error

$Today = (Get-Date)

$StartDate = $Today.Date.AddDays(-10)

$EndDate = $Today.Date.AddDays(1)

Invoke-VMScript -vm app12 -ScriptText "(Get-HotFix | Where {$_.InstalledOn -gt $using:StartDate -AND $_.InstalledOn -lt $using:EndDate }| Measure-Object).Count" -ScriptType PowerShell -GuestUser "abc\admin" -GuestPassword "password@123"

ScriptOutput

-----------------------------------------------------------------------------------------------------------------------

|  A Using variable cannot be retrieved. A Using variable can be used only with Invoke-Command, Start-Job, or

|  InlineScript in the script workflow. When it is used with Invoke-Command, the Using variable is valid only if the

|  script block is invoked on a remote computer.

|  At line:1 char:25

|  + ... ix | Where {$_.InstalledOn -gt $using:StartDate -AND $_.InstalledOn - ...

|  +                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

|      + CategoryInfo          : InvalidOperation: (:) [], RuntimeException

|      + FullyQualifiedErrorId : UsingWithoutInvokeCommand

|

|  A Using variable cannot be retrieved. A Using variable can be used only with Invoke-Command, Start-Job, or

|  InlineScript in the script workflow. When it is used with Invoke-Command, the Using variable is valid only if the

|  script block is invoked on a remote computer.

|  At line:1 char:25

|  + ... ix | Where {$_.InstalledOn -gt $using:StartDate -AND $_.InstalledOn - ...

|  +                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

|      + CategoryInfo          : InvalidOperation: (:) [], RuntimeException

|      + FullyQualifiedErrorId : UsingWithoutInvokeCommand

0 Kudos
LucD
Leadership
Leadership
Jump to solution

With Invoke-VMScript you can not use the using option, that only work with Start-Job and remote commands, like Invoke-Command.


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

0 Kudos
ganapa2000
Hot Shot
Hot Shot
Jump to solution

LucD,

I tried as below, still not getting any output

$script = @"

$Today = (Get-Date)

$StartDate = $Today.Date.AddDays(-10)

$EndDate = $Today.Date.AddDays(1)

(Get-HotFix | Where {$_.InstalledOn -gt $StartDate -AND $_.InstalledOn -lt $EndDate }| Measure-Object).Count

"@

$out = Invoke-VMScript -vm APP17 -ScriptText $script -ScriptType PowerShell -GuestUser "abc\admin" -GuestPassword "password@123"

$out

I am getting blank Output

ScriptOutput

-----------------------------------------------------------------------------------------------------------------------

|

-----------------------------------------------------------------------------------------------------------------------

0 Kudos
LucD
Leadership
Leadership
Jump to solution

You shouldn't be using double quotes for the inline script, then variable substitution will happen before you send the script.

Use single quotes.

This works for.

$script = @'

$Today = (Get-Date)

$StartDate = $Today.Date.AddDays(-10)

$EndDate = $Today.Date.AddDays(1)

(Get-HotFix | Where {$_.InstalledOn -gt $StartDate -AND $_.InstalledOn -lt $EndDate }| Measure-Object).Count

'@


$out = Invoke-VMScript -VM APP17 -ScriptText $script -ScriptType PowerShell -GuestUser "abc\admin" -GuestPassword "password@123"

$out


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

0 Kudos
ganapa2000
Hot Shot
Hot Shot
Jump to solution

Thank you LucD that worked.

I wanted to know, If I run multiple commands in the script block, how can I capture output from each command output into a variable ?

Eg:

Get-HotFix | Where {$_.InstalledOn -gt $StartDate -AND $_.InstalledOn -lt $EndDate }

(Get-HotFix | Where {$_.InstalledOn -gt $StartDate -AND $_.InstalledOn -lt $EndDate }| Measure-Object).Count

0 Kudos
LucD
Leadership
Leadership
Jump to solution

The easiest way to do this is to write different outputs to different files.

That is why I introduced the Infile and Outfile parameters in my Invoke-VMScriptPlus function in Invoke-VMScriptPlus V3

If you have to make do with Invoke-VMScript, you will have to use some trickery.

And that trickery is specific for the type of output you are looking at.

Something like this for example.

$code = @'

$StartDate = Get-Date '01/01/2020'

$EndDate = Get-Date


"### Output ###"

Get-HotFix | Where {$_.InstalledOn -gt $StartDate -AND $_.InstalledOn -lt $EndDate } | ConvertTo-Csv -UseCulture -NoTypeInformation

"### Output ###"

(Get-HotFix | Where {$_.InstalledOn -gt $StartDate -AND $_.InstalledOn -lt $EndDate }| Measure-Object).Count

'@


$sInvoke = @{

    VM = $vmName

    GuestCredential = $cred

    ScriptTYpe = 'powershell'

    ScriptText = $code

}

$dummy,$out1,$out2 = (Invoke-VMScript @sInvoke).ScriptOutput -split '### Output ###'

$out1 = $out1.TrimStart("`n`r") -split "`n`r"

$out2 = $out2.TrimStart("`n`r")


Write-Host "--> First output"

$out1 | ConvertFrom-Csv -UseCulture

Write-Host "--> Second output"

[int]$out2


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

0 Kudos
ganapa2000
Hot Shot
Hot Shot
Jump to solution

Thank you LucD, that worked.

One last thing, how can I use this for multiple VMs using import-csv ?

Eg:

Import-Csv -Path $reportlocation1 -UseCulture -PipelineVariable row |

ForEach-Object -Process {

$sInvoke = @{

    VM = $vmName

    GuestCredential = $Creds

    ScriptTYpe = 'powershell'

    ScriptText = $code

}

$dummy,$out1,$out2 = (Invoke-VMScript @sInvoke).ScriptOutput -split '### Output ###'

$out1 | Add-Member -MemberType NoteProperty -Name 'Patch_Count' -Value $patchcount -PassThru

$out1 = $out1.TrimStart("`n`r") -split "`n`r"

$out2 = $out2.TrimStart("`n`r")

Write-Host "--> First output"

$out1 | ConvertFrom-Csv -UseCulture

Write-Host "--> Second output"

[int]$out2

0 Kudos
LucD
Leadership
Leadership
Jump to solution

You could do something like this

$report1 = @()

$report2 = @()


Import-Csv -Path $reportlocation1 -UseCulture -PipelineVariable row |

ForEach-Object -Process {

    $sInvoke = @{

        VM              = $row.VmName

        GuestCredential = $cred

        ScriptTYpe      = 'powershell'

        ScriptText      = $code

    }

    $dummy, $out1, $out2 = (Invoke-VMScript @sInvoke).ScriptOutput -split '### Output ###'

    $out1 = $out1.TrimStart("`n`r") -split "`n`r"

    $out2 = $out2.TrimStart("`n`r")


    $report1 += $out1 | ConvertFrom-Csv -UseCulture | Select-Object -Property CSName, HotFixID, Description, Caption, InstalledOn, InstalledBy

    $report2 += New-Object -TypeName PSObject -Property ([ordered]@{

        VM    = $row.VmName

        Count = [int]$out2

    })

}


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

0 Kudos
ganapa2000
Hot Shot
Hot Shot
Jump to solution

Thank you LucD.

0 Kudos