Назад | Перейти на главную страницу

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
     }

Кажется, дает желаемые результаты.

Мое первое впечатление было неправильным, но я думаю, что это ваше решение. 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 
    }
}