Ошибка Invoke-Sqlcmd в L oop, ошибки не было один раз? - PullRequest
0 голосов
/ 09 апреля 2020

Если я запускаю этот скрипт .ps1-

$secID = Invoke-Sqlcmd -ServerInstance "MyDBServer" -Database "MyDataBase"-Query "SELECT SysID FROM dbo.SecurityLevels WHERE LEVELNAME LIKE '%User%';" 
Write-Host "MyDataBase"
Write-Host $secID.SysID

Я получаю на консоли следующее без ошибок -

MyDataBase
18

Однако, если я попробую этот же запрос в l oop в большем скрипте -

$dbservers = @('DataBaseServer1', 'DataBaseServer2')

foreach ($dbserver in $dbservers)
{
    $databases = Get-SqlDatabase -ServerInstance $dbserver | Where-Object { $_.Name -Match '\d{3,4}' -and $_.Name -notlike '*test*'}
    foreach ($database in $databases)
    {
            $secID = Invoke-Sqlcmd -ServerInstance $dbserver.Name -Database $database.Name -Query "SELECT SysID FROM dbo.SecurityLevels WHERE LEVELNAME LIKE '%User%';" 
            Write-Host $database.Name
            Write-Host $secID.SysID
    }
}

Я получаю правильный результат запроса, но на консоли перед ним появляются ошибки -

Invoke-Sqlcmd : A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that    
the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server) 
At \SQL.ps1:28 char:13                                                                                                      
+ ...    $secID = Invoke-Sqlcmd -ConnectionString $ConnectionString -Query  ...                                                                                                     
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                                                                         
    + CategoryInfo          : InvalidOperation: (:) [Invoke-Sqlcmd], SqlException                                                                                                   
    + FullyQualifiedErrorId : SqlExceptionError,Microsoft.SqlServer.Management.PowerShell.GetScriptCommand                                                                          

Invoke-Sqlcmd :                                                                                                                                                                     
At \SQL.ps1:28 char:13                                                                                                      
+ ...    $secID = Invoke-Sqlcmd -ConnectionString $ConnectionString -Query  ...                                                                                                     
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                                                                         
    + CategoryInfo          : ParserError: (:) [Invoke-Sqlcmd], ParserException                                                                                                     
    + FullyQualifiedErrorId : ExecutionFailureException,Microsoft.SqlServer.Management.PowerShell.GetScriptCommand*                                                                  
MyDataBase                                                                                                                                                                                                                                                                                                                                                            
18                                                                                                                                                                                  

Почему я получаю ошибки при его запуске в l oop против запуска его один раз? Кроме того, почему запрос работает, даже если я получаю ошибку? Я думаю, что мне чего-то не хватает, любая помощь будет принята с благодарностью!

1 Ответ

1 голос
/ 09 апреля 2020

Я думаю, это потому, что вы вызываете свойство Name для String, фактически ничего не возвращая. попробуйте это (я только что удалил вызов свойства $dbserver.Name to $dbserver):

$dbservers = @('DataBaseServer1', 'DataBaseServer2')

foreach ($dbserver in $dbservers)
{
    $databases = Get-SqlDatabase -ServerInstance $dbserver | Where-Object { $_.Name -Match '\d{3,4}' -and $_.Name -notlike '*test*'}
    foreach ($database in $databases)
    {
            $secID = Invoke-Sqlcmd -ServerInstance $dbserver -Database $database.Name -Query "SELECT SysID FROM dbo.SecurityLevels WHERE LEVELNAME LIKE '%User%';" 
            Write-Host $database.Name
            Write-Host $secID.SysID
    }
}

Ошибка должна быть в том, что он ищет экземпляр БД "", а он не находит его, и запрос может все еще go, хотя, потому что первый сервер может не иметь экземпляра, или потому что эти значения уже были загружены в свойства ранее. Но я просто размышляю, на самом деле я не использовал эти командлеты.

PS: , если вы хотите избежать вызова пустых свойств, добавьте Set-StrictMode -Version 2 в ваш скрипт, например:

PS > $text = "This is just a string"
PS > $text.AnyProperty
PS > Set-StrictMode -Version 2
PS > $text.AnyProperty
The property 'AnyProperty' cannot be found on this object. Verify that the property exists.
At line:1 char:1
+ $text.AnyProperty
+ ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], PropertyNotFoundException
    + FullyQualifiedErrorId : PropertyNotFoundStrict

Надеюсь, это поможет.

...