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
You could do something like this
$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
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
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
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
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
-----------------------------------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------------------------------
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.
$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
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
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.
$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
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
You could do something like this
$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
Thank you LucD.