后台作业中复制项目的凭据错误

时间:2021-01-24 17:34:10

标签: powershell

我有一个 PowerShell 脚本,它在多个服务器上调用一个函数作为后台作业。

在此函数中,有一个 Copy-Item 总是失败并显示以下错误消息:

Username or Passwort is incorrect.

我要将项目复制到的目标是 Synology NAS 上的网络共享。

这有点奇怪,因为默认情况下,运行后台作业的用户可以完全访问目标共享(我通过将 whoami 输出到日志文件来确保确实是该用户运行它)

但是,我还明确地再次将我的凭据加载到后台作业脚本块中,并为目标创建了一个 PSDrive 以确保我确实拥有访问权限,并且我还将凭据添加到了我的 Invoke-Command。怎么回事?

这是我的代码:

$Sources = @{
    "HV-Server" = Invoke-Command -ComputerName DC { Get-ADComputer -Filter "Name -like 'HV*'" } | Where-Object {
        Test-Connection $_.Name -Count 1 -ErrorAction SilentlyContinue
    } | Select-Object -ExpandProperty Name
}

$Destinations = @{
    "default" = "\\nas\Backup\VHDX"
}

. "\\server\install$\Powershell-Scripts\Functions\Security\Get-CustomCredential.ps1"
$Cred = Get-CustomCredential domain\myuser

Function Copy-VHDXToNAS {

    Param(
        [hashtable]$DestinationTable
    )

    Import-Module "Hyper-V"

    $BackupResult = Get-VM | Where-Object { $_.Name -notlike 'nob*' } | Get-VMHardDiskDrive | 
    Where-Object { !$_.Path.StartsWith("\\") } | ForEach-Object {

        . "\\server\install$\Powershell-Scripts\Functions\Security\Get-CustomCredential.ps1"
        $Cred = Get-CustomCredential domain\myuser

        $Destination = $DestinationTable.Get_Item($_.VMName)
        if (!$Destination) { $Destination = $DestinationTable.Get_Item("default") }
        New-PSDrive Nas -Root $Destination -PSProvider FileSystem -Credential $Cred > $null
        $Destination = Join-Path $Destination $_.VMName
        New-Item $Destination -ItemType Directory -ErrorAction SilentlyContinue > $null

        Try {
            Copy-Item $_.Path $Destination -Force -ErrorAction Stop
            $Result = "SUCCESS"
        }
        Catch {
            $a = whoami
            $Result = "ERROR: " + $_.Exception.Message + $a
        }

        [PSCustomObject]@{
            VMName = $_.VMName
            VHDXName = Split-Path $_.Path -Leaf
            Destination = $Destination
            Result = $Result
        }
    } 

    $BackupResult
}
    
$AllHosts = $Sources.Get_Item("HV-Server")
$Jobs = foreach ($HVHost in $AllHosts) {
    Invoke-Command -ComputerName $HVHost -ScriptBlock ${function:Copy-VHDXToNAS} -ArgumentList $Destinations -AsJob -Credential $Cred
}
$JobResult = $Jobs | Wait-Job | Receive-Job

1 个答案:

答案 0 :(得分:2)

正如 DougMaurer 所提到的,这确实是第二跳问题。我认为通过更新 Scriptblock 内的凭据,我不会遇到第二跳问题,但我做到了。

this Microsoft docs 中,他们讨论了第二跳问题以及如何解决它。我使用了 PSSessionConfiguration 方式 that is described here

基本上,您使用以下命令在远程服务器上创建会话配置:

$ConfigurationSplat = @{
    Name = "Your.ConfigurationName"
    Force = $true
    MaximumReceivedDataSizePerCommandMB = 200MB
    MaximumReceivedObjectSizeMB = 200MB
    RunAsCredential = $Cred
}
Register-PSSessionConfiguration @ConfigurationSplat

然后您可以像这样在 ConfigurationName 中使用 Invoke-Command

Invoke-Command -ComputerName $HVHost -ConfigurationName "Your.ConfigurationName" -ScriptBlock ${function:Copy-VHDXToNAS} -ArgumentList $Destinations -AsJob -Credential $Cred

这解决了第二跳问题。