0

I am writing a super-easy script in PowerShell. The target of this script is to read a list of server names from a txt file and a command block from another txt file. The result of the operation shold be a third txt file containing the information.

Here some code:

cls
$usr = Read-Host "Please insert username, you'll be asked for password later"
$path = Read-Host "Insert a valid path for ServerList.txt file"
$serverList = Get-Content -Path $path | Out-String

$path = Read-Host "Insert a valid path fom Command.txt file"
$commandBlock = Get-Content -Path $path | Out-String


echo "Command: " $commandBlock "will be executed on " $serverList
echo "Press CTRL+Z to abort or"
pause

Invoke-Command -ComputerName $serverList -ScriptBlock { $commandBlock } -credential $usr 

Serverlist.txt is a plain text containing something like "server1,server2,server3" and command.txt contain only this "Get-WmiObject Win32_BIOS | Select-Object SerialNumber"

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

I even tried to substitute $serverlist with $serverlist.toString() but it's not working. I read somewhere that in this case $serverlist is an Array, how do I do to make everything work?

Consider that https://technet.microsoft.com/en-us/library/hh849719.aspx Invoke-Commands work with "server1,server2,server3" format if you put the string via console.

2 Answers 2

2

Your $serverList isn't a list, it's a single string of server1,server2 etc. To make it into an array, you can use -split to split the string by commas.

$serverList = Get-Content -Path $path | Out-String
$serverList = $serverList -split ","
Sign up to request clarification or add additional context in comments.

10 Comments

The thing is that "server1,server2,server3" is what the invoke-command needs to work properly. I don't need to split! Don't I?
@BlacK When you input server1,server2,server3 as a naked argument, the PowerShell parser recognizes that it should be treated as three individual strings, not a single string. This is not the case when you pass a variable to it
You do, as if you're passing a variable, its value is used unparsed, so that your gwmi command searches a computer named server1,server2,server3 instead of going for three computers server1, server2, server3. But if your $serverList would be an array, then gwmi will see it and do a call on each computer.
@BlacK the last entry still has a trailing newline thanks to Out-String, see my answer below
@Vesper, you can get this "[`r`n]" by using this ​``"[`r`n]"``​.
|
1

For further understanding of why this doesn't work as you expect, please see the parsing and command syntax help files:

Get-Help about_Parsing
Get-Help about_Command_Syntax

$serverlist

When your text file contains the line server1,server2,server3, this command:

Get-Content -Path .\file.txt | Out-String

Just results in the string server1,server2,server3 and a newline - that's not a valid hostname.

Either format your text file like this (Get-Content automatically splits on line breaks):

server1
server2
server3

or split the string(s) from the file yourself:

$Serverlist = Get-Content -Path $Path | ForEach-Object { $_ -split "," }

$commandblock

For the command block part to work, you can't just drop a string into a ScriptBlock and expect it to execute - you need to recreate it as executable code:

$Code = Get-Content -Path $path -Raw
$CommandBlock = [scriptblock]::Create($Code)

# Now you can do this
Invoke-Command -ScriptBlock $CommandBlock

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.