7

I'm pulling my hair out here, because I just can't seem to get this to work, and I can't figure out how to google this issue. I'm running Powershell 2.0. Here's my script:

$computer_names = "server1,server2"
Write-Output "Invoke-Command -ComputerName $computer_names -ScriptBlock { 
    Get-WmiObject -Class Win32_LogicalDisk | 
    sort deviceid | 
    Format-Table -AutoSize deviceid, freespace 
}"
Invoke-Command -ComputerName $computer_names -ScriptBlock { 
    Get-WmiObject -Class Win32_LogicalDisk | 
    sort deviceid | 
    Format-Table -AutoSize deviceid, freespace 
}

The last command gives the error:

Invoke-Command : One or more computer names is not valid. If you are trying to 
pass a Uri, use the -ConnectionUri parameter or pass Uri objects instead of 
strings.

But when I copy the output of the Write-Output command to the shell and run that, it works just fine. How can I cast the string variable to something that Invoke-Command will accept? Thanks in advance!

erictheavg
  • 350
  • 2
  • 3
  • 14

4 Answers4

6

Jamey and user983965 are correct, in that your declaration is wrong. However foreach here is not mandatory. If you just fix your array declaration like this, it will work:

$computer_names = "server1","server2"
Invoke-Command -ComputerName $computer_names -ScriptBlock { 
    Get-WmiObject -Class Win32_LogicalDisk | 
    sort deviceid | 
    Format-Table -AutoSize deviceid, freespace 
}
Andrew Savinykh
  • 25,351
  • 17
  • 103
  • 158
  • Another way to populate the array to work this way if you have already populated a variable called `$computers` with computer objects (for example using `get-adcomputer` is `$computer_names = $computers.name`. – Todd Wilcox Jan 20 '18 at 13:47
5

You declared your array incorrectly. Put a comma between strings and pipe it to for-each like:

$computer_names = "server1", "server2";

$computer_names | %{
   Write-Output "Invoke-Command -ComputerName $_ -ScriptBlock {

    ...snip
Jamey
  • 1,595
  • 9
  • 23
  • That did it, thanks! I didn't think to just run a for-each on it. That's shorthand I haven't seen. But, I was avoiding declaring an array because I didn't think Invoke-Command -ComputerName takes one--instead, it takes a list of computer names separated by one comma, no spaces. Am I wrong? – erictheavg Apr 10 '12 at 22:47
  • Responding to myself: it looks so. I just read the help on that command and it say it expects a string[]. I was going off of the examples alone and made a bad assumption. – erictheavg Apr 10 '12 at 22:56
1

If you're getting an array of computers from active directory too - like this:

$computers = Get-ADComputer -filter {whatever}

Make sure you remember to select/expand the results.. like this:

$Computers= Get-ADComputer -filter * | Select-Object -ExpandProperty Name

Then...

Invoke-Command -ComputerName $Computers -ScriptBlock {Do Stuff}

Zack A
  • 688
  • 5
  • 11
0

have you tried:

$computer_names = "server1" , "server2"

foreach ($computer in $computer_names)
{
Write-Output "Invoke-Command -ComputerName $computer -ScriptBlock { 
    Get-WmiObject -Class Win32_LogicalDisk | 
    sort deviceid | 
    Format-Table -AutoSize deviceid, freespace 
}"
Invoke-Command -ComputerName $computer -ScriptBlock { 
    Get-WmiObject -Class Win32_LogicalDisk | 
    sort deviceid | 
    Format-Table -AutoSize deviceid, freespace 
}
}
user983965
  • 1,111
  • 3
  • 17
  • 31