0

我正在尝试使用 Powershell 7-Preview 执行 Powershell 脚本(7.0)文件,该文件遍历所有数据库并在所有数据库中执行 SQL Server 脚本。

该脚本正确获取所有数据库,但是,当 Parallel 块执行时,我收到此错误(有关详细信息,请参阅下面的屏幕截图)。

无法验证参数“用户名”的参数。参数为 null 或空。提供一个不为 null 或空的参数,然后重试该命令。

命令 - C:\GitHub\TempApp\CompanyTemplate\bin\debug\DeploymentScripts\PowerShell\DeployCompanyDatabases.ps1

Param
(
    [string]$SystemWorkingDir,
    [string]$DatabaseUsername,
    [string]$DatabasePassword,
    [string]$DacpacLocation,
    [string]$OngoingChangesScriptLocation,
    [string]$PreDeploymentBugFixScriptLocation,
    [string]$DropExternalTablesScriptLocation
)

    $SystemWorkingDir = "C:\GitHub\TempAPP\CompanyTemplate\bin\Debug" 
    $DatabaseUsername = "tempDB"
    $DatabasePassword = "tempPassword" 
    $DacpacLocation = "CompanyTemplate.dacpac" 
    $OngoingChangesScriptLocation = "DeploymentScripts\OnGoingDataChanges.sql" 
    $PreDeploymentBugFixScriptLocation = "DeploymentScripts\PreDeployment.sql"
    $DropExternalTablesScriptLocation = "DeploymentScripts\DropExternalTables.sql"
    [string]$ServerInstance = "tempDB"

$GetDatabasesParams = @{
    "Database" = "master"
    "ServerInstance" =  "tempDB"
    "Username" = "$DatabaseUsername"
    "Password" = "$DatabasePassword"
    "Query" = "select [name] from sys.databases where [name] like 'Company%'"
    "ConnectionTimeout" = 9999
}

echo "Retrieving company database names"
[string[]]$DatabaseNames = Invoke-Sqlcmd @GetDatabasesParams | select -expand name

[int]$ErrorCount = 0
$DatabaseNames | ForEach-Object -Parallel {
    try 
    {
        $OngoingChangesScriptParams = @{
            "Database" = "$_"
            "ServerInstance" = "$ServerInstance"
            "Username" = "$DatabaseUsername"
            "Password" = "$DatabasePassword"
            "InputFile" ="$SystemWorkingDir\$OngoingChangesScriptLocation" 
            "OutputSqlErrors" = 1
            "QueryTimeout" = 9999
            "ConnectionTimeout" = 9999
        }

        Invoke-Sqlcmd @OngoingChangesScriptParams       
    }
    catch
    {
        $ErrorCount++
        echo "Internal Error. The remaining databases will still be processed."
        echo $_.Exception|Format-List -force
    }
}

错误: 我一个

4

1 回答 1

0

这个问题与Send string parameters to a Start-Job script block不太一样,但答案与https://stackoverflow.com/a/63702220/3156906..几乎相同。

问题是脚本块中的$DatabaseUsernameand$DatabasePassword等变量在foreach-object不同的范围内,并且实际上是与主脚本中的变量不同的变量。

您可以使用使用范围修饰符来解决此问题

对于在会话外执行的任何脚本或命令,您需要使用范围修饰符从调用会话范围嵌入变量值,以便会话外代码可以访问它们。

所以而不是:

$DatabaseUsername = "myusername"

foreach-object -parallel {
    ...
    "Username" = $DatabaseUsername
    ...
}

尝试

$DatabaseUsername = "myusername"

foreach-object -parallel {
    ...
    "Username" = $using:DatabaseUsername
    ...
}
于 2020-09-09T14:31:37.327 回答