I'm loading a json file that contains a list of computer names and each of them contains a list of files I need to operate on. For this example, I'm just displaying the file sizes.
But I'm getting file not found errors. I think it's because new-pssession
is not activated or opened. I confirmed the file does exist on the remote computers. Is there something I need to do to "activate/open" the session after new-pssession
?
$cred = Get-Credential -UserName admin -Message "Enter Password"
$computers = Get-Content "sample.json" | ConvertFrom-Json
foreach($computer in $computers){
$s = new-pssession -ComputerName $computer.computer -Credential $cred
foreach($file in $computer.files){
write-host $file has (get-item $file).length "bytes"
}
remove-pssession $s
}
json file
[
{
"computer": "machine1",
"files": [
"c:\\temp\\done.png",
"c:\\temp\\Permissions.xlsx"
]
},
{
"computer": "machine2",
"files": [
"c:\\software\\TortoiseSVN.msi",
"c:\\software\\TortoiseSVN.txt"
]
}
]
As mklement0 points out in his helpful comment, New-PSSession
will only establish the persistent connection with the remote hosts, however if you need to execute code on them you would need to use Invoke-Command
.
I have removed New-PSSession
for this example as there is no need for it in this case, but note, when using a PSSession, you would be using the -Session
parameter instead of -ComputerName
.
$cred = Get-Credential -UserName admin -Message "Enter Password"
$computers = Get-Content "sample.json" | ConvertFrom-Json
foreach($computer in $computers)
{
Invoke-Command -ComputerName $computer.computer {
$computer = $using:computer
foreach($file in $computer.files)
{
Write-Host "$file has $((Get-Item $file).Length) bytes"
}
} -Credential $cred
}
Since Invoke-Command
allows parallel execution of script blocks on remote hosts, the same can be done with your code, however it would be a bit more complex. $computers
would be passed to each remote session and each host would need to figure out which object
of the object[]
has to run:
$cred = Get-Credential -UserName admin -Message "Enter Password"
$computers = Get-Content "sample.json" | ConvertFrom-Json
Invoke-Command -ComputerName $computers.computer {
$computers = $using:computers
$files = $computers.Where({ $_.computer -eq $env:ComputerName }).files
foreach($file in $files)
{
Write-Host "$file has $((Get-Item $file).Length) bytes"
}
} -Credential $cred