I am trying to get the list of machines which are in particular state (Saved, Running, Stopped). I am passing the state of the machine as an argument in a function.
Function global:Resource-Summary
{
Param(
[parameter(mandatory=$true)] $ProgramName,
[parameter(mandatory=$true)] $ServerName
)
PROCESS
{
Foreach ($Server in $ServerName)
{
Invoke-Command -ComputerName $Server -ScriptBlock {
$VMs = Get-VM
$colVMs = @()
foreach ($VM in $VMs)
{
$objVM = New-Object System.Object
$objVM | Add-Member -MemberType NoteProperty -Name VMName -Value $VM.VMName
$objVM | Add-Member -MemberType NoteProperty -Name VMNotes -Value $VM.Notes
$objVM | Add-Member -MemberType NoteProperty -Name VMState -Value $VM.State
$colVMs += $objVM
}
$a = @{Expression={$_.VMName};Label='VM Name'}, `
@{Expression={$_.VMNotes};Label='VM Description'}, `
@{Expression={$_.VMState};Label='State'}
"Program Name : $ProgramName"
$colVMs |Where-Object {($_.VMState -eq '$ProgramName')} | Format-Table $a -AutoSize
} -ArgumentList $ProgramName
}
}
}
When I run Resource-Summary -ProgramName Running -ServerName Demo
I do not get any value.
When I replace $ProgramName
with RUNNING
I get the expected output.
For reference, see e.g. this post on how Pass arguments to a scriptblock in powershell .
The problem in your script is how you call the script block, this is explained in more detail in the link above, but you need to pass any "external" input to it the same way as if you'd call it like a function.
You are doing this partially correctly, you are using the -ArgumentList
parameter to send $ProgramName
to the scriptslock but you haven't specified in the scriptblock how to access it.
For example, check out
Invoke-Command -ArgumentList "Application" -ScriptBlock {
param($log)
Get-EventLog $log
}
Here -ArgumentList
contains the input, and inside the scriptblock, $log
is assigned its value.
Updating your script to take that into account:
Function global:Resource-Summary
{
Param(
[parameter(mandatory=$true)] $ProgramName,
[parameter(mandatory=$true)] $ServerName
)
PROCESS
{
Foreach ($Server in $ServerName)
{
Invoke-Command -ComputerName $Server -ScriptBlock {
param($name)
$VMs = Get-VM
$colVMs = @()
foreach ($VM in $VMs)
{
$objVM = New-Object System.Object
$objVM | Add-Member -MemberType NoteProperty -Name VMName -Value $VM.VMName
$objVM | Add-Member -MemberType NoteProperty -Name VMNotes -Value $VM.Notes
$objVM | Add-Member -MemberType NoteProperty -Name VMState -Value $VM.State
$colVMs += $objVM
}
$a = @{Expression={$_.VMName};Label='VM Name'}, `
@{Expression={$_.VMNotes};Label='VM Description'}, `
@{Expression={$_.VMState};Label='State'}
"Program Name : $ProgramName"
$colVMs |Where-Object {($_.VMState -eq "$name") | Format-Table $a -AutoSize
}
} -ArgumentList $ProgramName
}
}
}
Also, in my opinion, the -ArgumentList
is on the wrong line, it needs to be after the following closing bracket, one line done. This way it's on the same cmdlet as Invoke-Command
and the scriptblock.