Не удается преобразовать значение «/Action:» типа «System.Строку» в тип «System.Management.Автоматизация.ScriptBlock»

#powershell #powershell-7.0

#powershell #powershell-7.0

Вопрос:

Я получаю эту ошибку при попытке выполнить приведенный ниже скрипт power-shell (7.0). Этот скрипт обновляет все базы данных с помощью файла dacpac и SqlPackage.exe .

 [string]$SqlPackagePath = "C:Program Files (x86)Microsoft Visual Studio2019EnterpriseCommon7IDEExtensionsMicrosoftSQLDBDAC150SqlPackage.exe"
[int]$ErrorCount = 0
$DatabaseNames | ForEach-Object -Parallel {
    
    echo "$_ - Updating database using DACPAC."
    
    dir -Path "C:Program Files (x86)Microsoft Visual Studio*" -Filter "SqlPackage.exe" -Recurse -ErrorAction SilentlyContinue | %{$_.FullName} {$using:SqlPackagePath /Action:Publish /tu:$using:DatabaseUsername /tp:$using:DatabasePassword /tsn:$using:ServerInstance /tdn:"$_" /sf:using:$DacpacLocation /p:BlockOnPossibleDataLoss=False}
        
  }
  

Я новичок в powershell script. Похоже, проблема, похоже, в способе передачи аргументов, поэтому я просто поместил {} вокруг аргументов, поскольку я получал другую ошибку ниже для параметра $using:SqlPackagePath, но, похоже, это не работает

Не удается преобразовать значение «somepath» типа «System.Строку» в тип «System.Management.Автоматизация.ScriptBlock».

Комментарии:

1. Неясно, что вы пытаетесь здесь сделать — это $SqlPackagePath имя исполняемого файла, который вы пытаетесь выполнить? И полный путь к SqlPackage.exe является одним из аргументов?

2. Да, с помощью команды ‘dir’ этот скрипт ищет SqlPackage .exe по указанному пути, если не находит, то полный путь к SqlPackage.exe передается через переменную $SqlPackagePath. Затем, используя этот exe-файл, он устает обновлять все базы данных, используя файл dacpac в цикле for.

Ответ №1:

Вы не можете «экранировать» аргументы, вложив их в литералы блока сценария.

Похоже, вы хотите сделать:

 [string]$SqlPackagePath = "C:Program Files (x86)Microsoft Visual Studio2019EnterpriseCommon7IDEExtensionsMicrosoftSQLDBDAC150SqlPackage.exe"
[int]$ErrorCount = 0
$DatabaseNames | ForEach-Object -Parallel {
    
    echo "$_ - Updating database using DACPAC."

    # locate SqlPackage, otherwise default to `$SqlPackagePath` from calling scope
    $sqlPackageExe = dir -Path "C:Program Files (x86)Microsoft Visual Studio*" -Filter "SqlPackage.exe" -Recurse -ErrorAction SilentlyContinue |Select -First 1
    if(-not $sqlPackageExe){
        $sqlPackageExe = $using:SqlPackagePath
    }

    # use the `amp;` invocation operator to execute SqlPackage
    amp; $sqlPackageExe /Action:Publish /tu:$using:DatabaseUsername /tp:$using:DatabasePassword /tsn:$using:ServerInstance /tdn:"$_" /sf:$using:DacpacLocation /p:BlockOnPossibleDataLoss=False        
}
  

Комментарии:

1. Я попробовал это решение, но теперь получаю эту ошибку -> out-lineoutput: объект типа «Microsoft. PowerShell. Команды. Внутренний. Формат. FormatStartData» недопустим или находится не в правильной последовательности. Вероятно, это вызвано заданной пользователем командой «format-list», которая противоречит форматированию по умолчанию.

2. Использовали ли вы какие-либо Format-* команды (или ft или fl ) для какой-либо из переменных, на которые вы ссылаетесь $using: ?

3. Нет, это утверждение вызывает проблему, которая возвращает таблицу с 3 строками. Мне нужна только 1-я запись, т.Е. Полный путь к exe. $sqlPackageExe = dir -Path » .C:Program Файлы (x86) Microsoft Visual Studio*» -Filter «SqlPackage.exe » -Recurse -ErrorAction Silently continue. Как я могу получить 1-ю запись или путь?

4. Пропустите его |Select -First 1 , обновил ответ