用于创建文件夹并将文件复制到远程服务器的 Powershell 脚本 选项 1:使用 Invoke-Command选项 2:没有 Invoke-Command

问题描述

我编写了一个下面的 PowerShell 脚本来在远程计算机上创建一个文件夹(如果不存在)并将文件复制到远程位置,我收到以下错误,任何人都可以帮助解决这个问题。

$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
        }
    }
}

错误

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

我注意到在 if 循环开始后,$server 变量数据正在释放,不知道为什么会发生这种情况。

解决方法

因此,正如我在评论中所说,您有 2 个选项可以将脚本从远程主机复制到另一个远程主机。

第一个选项可能会给您一个双跳错误,如果是这种情况,您应该查看CredSSP服务主体名称/Kerberos委托

选项 1:使用 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   
}

选项 2:没有 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
}

现在,要了解 $using:如何在远程主机上使用本地变量,这里是 Example 9 of MS Docs 的链接,它解释了真的很好。

您也可以使用 -ArgumentList 将变量传递给远程主机,然后使用 $args 自动变量或 param(...) 块。

,

尝试用以下内容替换此行 \$server\D$\scripts 以使其正确扩展(您的错误代码显示三个反斜杠)

"\\$server\D$\scripts"

我觉得这个脚本可以一起使用重写 - 如果您在远程计算机上调用命令,您可以直接引用该计算机的文件夹结构,而无需使用远程共享。

例如,使用 "D:\scripts" 而不是 \\server1\D$\scripts