Сценарий PowerShell не выполняет команду bcp должным образом

У меня есть следующая часть функции, которая сводит меня с ума. Как видите, я генерирую путь и имя файла для массового копирования данных таблицы. Когда я запускаю это в сценарии PowerShell, я получаю следующую ошибку:

C:\Program Files\Microsoft SQL Server\100\Tools\Binn\bcp.exe:  unknown option 1
usage: C:\Program Files\Microsoft SQL Server\100\Tools\Binn\bcp.exe

Однако, когда я копирую строку вывода, полученную от команды Write-host, и вставляю ее в командную строку, я могу выполнить ее без проблем. Что дает?

ForEach($table in $db.Tables | where {$_.IsSystemObject -eq $false})
{

        $fullName = "$db.$table"

        If($scriptTables -contains $fullName)
        {
              $fullFilePath = (pwd).path + "\$db.$table" + ".dat"
              $copyExecString = "$db.$table out `"$fullFilePath`" -E -N -Sserver1\instance -Uxyz -Pxyz > Output.txt"
              & bcp "$copyExecString" #Invoke-Expression "bcp $copyExecString"
              Write-host "bcp $copyExecString"                      
        }

}

Пример вывода:

bcp [DB].[dbo].[Table] out "C:\Development\ScriptDemoData\[DB].[dbo].[Table].dat" -E -N -Sserver1\instance -Uxyz -Pxyz > Output.txt

person TechDawg270    schedule 21.03.2012    source источник


Ответы (3)


Я не знаю, как расширить строку до различных свойств.

Однако вы можете просто передать их напрямую.

.\bcp.exe $db.$table out "$fullFilePath" -E -N -Sserver1\instance -Uxyz -Pxyz > Output.txt
person Guvante    schedule 22.03.2012

Это связано с выполнением устаревших команд в Powershell, иногда оператор вызова (&) будет работать, а иногда - нет, особенно если есть много аргументов, как в случае с bcp.exe. Другой способ выполнить устаревшие приложения - использовать start-process. Я переработал ваш код и успешно протестировал следующее.

try {add-type -AssemblyName "Microsoft.SqlServer.ConnectionInfo, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" -EA Stop}
catch {add-type -AssemblyName "Microsoft.SqlServer.ConnectionInfo"}

try {add-type -AssemblyName "Microsoft.SqlServer.Smo, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" -EA Stop; $smoVersion = 10}
catch {add-type -AssemblyName "Microsoft.SqlServer.Smo"; $smoVersion = 9}

$ServerInstance = "$env:computername\sql1"
$Database = 'AdventureWorks'
$server = new-object ("Microsoft.SqlServer.Management.Smo.Server") $ServerInstance
$db = $server.Databases[$Database]
$scriptTables = ,'[AdventureWorks].[Sales].[StoreContact]'

ForEach($table in $db.Tables | where {$_.IsSystemObject -eq $false})
{

        $fullName = "$db.$table"

        If($scriptTables -contains $fullName)
        {
              $fullFilePath = (pwd).path + "\$db.$table" + ".dat"
              start-process -NoNewWindow -RedirectStandardOutput output.txt -FilePath bcp -ArgumentList @"
$db.$table out "$fullFilePath" -E -N -S$ServerInstance -T
"@
        }

}
person Chad Miller    schedule 22.03.2012

Я подозреваю, что это из-за цитат.

bcp "$copyexecstring" заключит ваши параметры в двойные кавычки.

Для упрощения я бы поместил $ bcp внутри строки, а затем просто использовал Invoke-Expression:

$copyExecString = "$db.$table out `"$fullFilePath`" -E -N -Sserver1\instance -Uxyz -Pxyz > Output.txt"
$copyexecstring = "bcp $copyexecstring"
$return = (Invoke-expression $copyexecstring) | Out-string
person JNK    schedule 22.03.2012
comment
" вызывает раскрытие переменных. ' нет. Я не верю, что ни один из них передается исполняющей функции (они удаляются ОС) - person Guvante; 02.10.2012