Invoke-Sqlcmd -InputFile“\\UNC\Path”访问被拒绝?

Invoke-Sqlcmd -InputFile“\\UNC\Path”访问被拒绝?

我正在编写一个概念验证 Powershell 脚本,该脚本将在源主机上调度SOURCEHOST01并调用远程 SQL 服务器SQLSERV01&上的命令SQLSERV02。计划的操作顺序如下:

  1. 从源主机上存储的文本文件中获取 SQL 服务器主机名列表 \\SOURCEHOST01\PATH\SQLSERVERHOSTNAME.LIST

  2. 对于每个 SQL 服务器,调用一个命令将 SQL 脚本复制 \\SOURCEHOST01\PATH\simple_sp_who.sql%TEMP%每个 SQL 服务器上。

  3. Invoke-Sqlcmd在每个 SQL 服务器上使用指定的 SQL 脚本。

这是我迄今为止的代码:

Get-Content \\SOURCEHOST01\PATH\SQLSERVERHOSTNAME.LIST | Foreach-Object {
    Invoke-Command -ComputerName $_ -ScriptBlock {
        $FileSource = "\\SOURCEHOST01\PATH\"
        $FileDest = "$Env:TEMP\SQL\"
        $Database = "Master"
        $InputFile = "$FileDest\simple_sp_who.sql"
        Copy-Item $FileSource -Destination $FileDest -Recurse
        Invoke-Sqlcmd -ServerInstance $_ -Database $Database -InputFile $InputFile 
    }
}

产生的错误:

Access is denied
+ CategoryInfo          : PermissionDenied: (\\SOURCEHOST01\PATH\:String) [Copy-Item], UnauthorizedAccessException
+ FullyQualifiedErrorId : ItemExistsUnauthorizedAccessError,Microsoft.PowerShell.Commands.CopyItemCommand
+ PSComputerName        : SQLSERV01

由于文件权限问题,脚本似乎在 Copy-Item 处失败。我运行的测试环境以域管理员身份运行所有内容。我确信这是我忽略的简单问题,但我已经开始重复这些步骤,所以我需要一双全新的眼睛。

编辑:

这就是我最终得到的结果:

    Get-Content \\SOURCEHOST01\PATH\SQLSERVERHOSTNAME.LIST | Foreach-Object {
            $SQLSource = Test-Path "\\$($_)\C$\Windows\Temp\SQL\"
            $FileSource = "\\SOURCEHOST01\PATH\"
            $FileDest = "\\$($_)\C$\Windows\Temp\SQL\"
    IF ($SQLSource -eq $True) {
        Remove-Item -Recurse -Force $FileDest
        Copy-Item -Recurse $FileSource $FileDest
    } ELSE {
        Copy-Item -Recurse $FileSource $FileDest
    }
            $date = Get-Date -UFormat "%Y%m%d-%H%M"
            $ScriptBlockContent = {
                $Database = "Master"
                $InputFile = "C:\Windows\Temp\SQL\simple_sp_who.sql"
            Invoke-Sqlcmd -ServerInstance $_ -Database $Database -InputFile $InputFile
            }
        Invoke-Command -ComputerName $_ -ScriptBlock $ScriptBlockContent | Out-File -filePath "\\SOURCEHOST01\PATH\Logs\$date-$_.rpt" -NoClobber
     }

似乎产生了预期的结果。

答案1

我的第一印象是错误的,但我认为这是您的解决办法。Invoke-Command存在双跳身份验证问题(尝试连接到远程计算机,然后从那里连接到网络共享)。可以使用 CredSSP 修复此问题,它有自己的一套步骤和安全问题。

为了避免CredSSP的复杂性和安全漏洞,这可能是从另一个角度进行的修复:

$Database = "Master"
$InputFile = "C:\Windows\Temp\SQL\simple_sp_who.sql"

Get-Content \\SOURCEHOST01\PATH\SQLSERVERHOSTNAME.LIST | Foreach-Object {
    Copy-Item -Path "\\SOURCEHOST01\PATH\" -Destination "\\$($_)\C$\Windows\Temp\SQL" -Recurse
    Invoke-Command -ComputerName $_ -ScriptBlock {
        Invoke-Sqlcmd -ServerInstance $_ -Database $Database -InputFile $InputFile 
    }
}

相关内容