Reputation: 75
I written a below PowerShell script to create a folder on remote computer if not exist and copy the file into the remote location, I am getting the below error can anyone help on this.
$serverlist = Get-Content "C:\serverlist.txt"
foreach ($server in $serverlist){
Invoke-Command -ComputerName $server -ScriptBlock {
$testpath = Test-Path "\\$server\D$\scripts"
if($testpath -eq $true)
{
Write-Host "Path exist on $env:COMPUTERNAME, copying scirpt to the location"
Copy-Item -Path \\hostx\copyshare\scirpts\IISLog.ps1 -Destination \\$server\D$\scripts -PassThru
}
else
{
#create a new folder on C drive
Write-Host "Creating new folder...... "
New-Item -Path \\$server\D$ -Name "scripts" -ItemType Directory
sleep -Seconds 4
Write-Host "Copying the script to destination...."
Copy-Item -Path \\hostx\copyshare\scirpts\IISLog.ps1 -Destination \\$server\D$\scripts -Verbose
}
}
}
Error
The path is not of a legal form.
+ CategoryInfo : InvalidArgument: (\\\D$\scripts:String) [New-Item], ArgumentException
+ FullyQualifiedErrorId : CreateDirectoryArgumentError,Microsoft.PowerShell.Commands.NewItemCommand
+ PSComputerName : XXHOST
The network path was not found.
+ CategoryInfo : NotSpecified: (:) [Copy-Item], IOException
+ FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.CopyItemCommand
+ PSComputerName : XXHost
I have noticed after once the if loop is started the $server
variable data is releasing not sure why this happened.
Upvotes: 0
Views: 6938
Reputation: 1
Try replacing this line \$server\D$\scripts with the following so that it expands correctly (your error code shows three backslashes)
"\\$server\D$\scripts"
I feel that this script could use a re-write all together - if you're invoking a command on a remote computer, you can reference that computers folder structure directly without using remote shares.
For example, use "D:\scripts"
instead of \\server1\D$\scripts
Upvotes: 0
Reputation: 59900
So, as I said in my comment, you have 2 options to copy the script from a remote host to another remote host.
It is possible that the first option may give you a double-hop error, if that was the case you should be looking at CredSSP
or Service Principal Name / Kerberos Delegation.
Invoke-Command
$serverlist = Get-Content "C:\serverlist.txt"
$scriptBlock = {
# Since this is already happening on the scope of $server (remote host)
# you don't really need to use a network path.
# If you still want to use it, you can do, \\localhost\D$\scripts too.
if(-not(Test-Path "D:\scripts"))
{
Write-Host "Creating new folder...... "
New-Item -Path "D:\scripts" -ItemType Directory
}
sleep -Seconds 4
Write-Host "Copying the script to destination...."
# Not sure if "scirpts" is intended or a typo here
Copy-Item -Path "\\hostx\copyshare\scirpts\IISLog.ps1" -Destination "D:\scripts\" -Verbose
}
foreach ($server in $serverlist)
{
Invoke-Command -ComputerName $server -ScriptBlock $scriptBlock
}
Invoke-Command
$serverlist = Get-Content "C:\serverlist.txt"
foreach ($server in $serverlist)
{
if(-not(Test-Path "\\$server\D$\scripts"))
{
Write-Host "Creating new folder...... "
New-Item -Path "\\$server\D$\scripts" -ItemType Directory
}
sleep -Seconds 4
Write-Host "Copying the script to destination...."
Copy-Item -Path "\\hostx\copyshare\scirpts\IISLog.ps1" -Destination "\\$server\D$\scripts\" -Verbose
}
Now, to understand the $using:
, or how to use local variables on remote hosts, here is a link for Example 9 of MS Docs which explains it really well.
You can also use -ArgumentList
to pass the variables to the remote host, and then use the $args
automatic variable or a param(...)
block.
Upvotes: 1