web-dev-qa-db-ja.com

Invoke-Sqlcmd -InputFile "\\ UNC \ Path"アクセスが拒否されましたか?

ソースホストでスケジュールされる概念実証Powershellスクリプトに取り組んでいますSOURCEHOST01そしてリモートSQLサーバーでコマンドを呼び出すSQLSERV01SQLSERV02。計画されている操作の順序は次のとおりです。

  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
     }

望ましい結果が得られるようです。

2
Confusias

私の第一印象は間違っていましたが、これはあなたの修正だと思います。 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 
    }
}
2
Cory Knutson