Какое отношение Query имеет к Get-Member? - PullRequest
0 голосов
/ 11 июля 2019

У меня есть 2 сценария.

Script1 имеет следующее:

function Query($Query) {
    $SqlConnection = New-Object System.Data.SqlClient.SqlConnection 
    $SqlConnection.ConnectionString = "Server=$DB_Server;Initial Catalog=$Database;Integrated Security=SSPI" 
    $SqlCmd = New-Object System.Data.SqlClient.SqlCommand 
    $SqlCmd.Connection = $SqlConnection 
    $SqlCmd.CommandText = $Query 
    $SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter 
    $SqlAdapter.SelectCommand = $SqlCmd 
    $DataSet = New-Object System.Data.DataSet 
    $a = $SqlAdapter.Fill($DataSet)
    $SqlConnection.Close() 
    $DataSet.Tables[0]
}

#create .net array object for csv export
$exportObject = New-Object System.Collections.ArrayList
#create ordered dictionary so column names come out in the ordered they were created
$rowObject = [ordered]@{}

$connection_string = "Connection Timeout=120;User Id=UID1;Data Source=datasource.com;Password=password12!553"

$rowObject.'Connection Details' = $connection_string

#INSERT connection string into Table
Query "UPDATE [$someTable]
SET [connection_string] = '$connection_string'
WHERE [cname] = '$cinput' AND ([pserver] = '$pinput'"

$exportObject.Add((New-Object PSObject -Property $rowObject)) | Out-Null

$exportObject | Select-Object

Теперь в script2 я вызываю script1 и "out-variable" объект тогдапреобразовать его в PSCustomObject, чтобы использовать его с табличной функцией HTML (не относится к этой теме, поэтому не будет включать в код. Подробнее об этом здесь ).

Script2:

& ".\script1.ps1" -ViewConnection "$cinput" -OutVariable xprtOut | Format-Table -Wrap

#converting xprtOut from Arraylist to pscustomobject to be used with ConvertTo-HTMLTable
$Arr = @()
foreach ($Object in $xprtOut) {
    $i = -1
    $arrayListCount = -($Object | gm | Where-Object {$_.MemberType -like "noteproperty"}).Count

    $customObj = New-Object PSCustomObject
    do {
        $customObj | Add-Member -MemberType NoteProperty -Name (($Object | gm)[$($i)].Name) -Value ($Object."$(($Object | gm)[$($i)].Name)")
        $i--
    } while ($i -ge $arrayListCount)

    $Arr += $customObj
}

, когда я запускаю script2, я получаю следующие ошибки:

gm : You must specify an object for the Get-Member cmdlet.
$arrayListCount = -($Object | gm | Where-Object {$_.MemberType -l ...

Cannot index into a null array.
... dd-Member -MemberType NoteProperty -Name (($Object | gm)[$($i)].Name) ...

После некоторой длительной отладки я обнаружил корневую проблему: удалив UPDATEоператор запроса из script1 прекратил работать с script2, и он начал нормально работать.

Итак, вопрос в том, почему оператор запроса в script1 будет проблематичным?Какое это имеет отношение к преобразованию объекта?

1 Ответ

1 голос
/ 12 июля 2019

У вас есть проблема с форматированием вывода первого скрипта, когда вы выводите его как переменную, о которой я уже упоминал. Если вы решите проблему с оператором Update, то я бы проверил, правильно ли синтаксически анализируется в PowerShell. Также не ясно, как ваша функция получает значения $ DB_Server и $ Database. Я не совсем уверен, что это решит вашу проблему, но я думаю, что код для вашей функции запроса может быть упрощен, и вот минимальный пример, который работает для меня.

function Query {
    Param (
        [parameter(Mandatory=$true,Position = 0)][string]$SqlConnection,
        [parameter(Mandatory=$true, Position = 1)][string]$Data
    )

    # Create a new connection
    $SqlClient = New-Object System.Data.SqlClient.SqlConnection($SqlConnection)
    $SqlClient.Open()

    # Submit the query
    $Query = "UPDATE <tablename> SET <column_name> = '$Data' WHERE <column_name> = '<value>'"
    # You may want to comment out the rest of the function here and see how your Query looks.
    $Command = New-Object System.Data.SqlClient.SqlCommand($Query,$SqlClient)
    $DataSet = New-Object System.Data.DataSet
    $DataAdapter = New-Object System.Data.SqlClient.SqlDataAdapter($Command)
    $DataAdapter.Fill($DataSet) | Out-Null

    # Close and return your data. You may want to dispose of the client too.
    $DataSet.Tables[0]
    $SqlClient.Close()
    $SqlClient.Dispose()
}

$UserConnection = "Connection Timeout=120;User Id=UID1;Data Source=datasource.com;Password=password12!553"
$SqlConnection = "Server=<Server\Instance>; Database=<Database_Name>; Integrated Security=True; Connect Timeout=15"
Query -SqlConnection $SqlConnection -Data $UserConnection

Затем вы можете захотеть перебрать пользовательский объект SQL-соединений и пользовательские соединения, которые вы хотите добавить и создать свой выходной объект таким способом. Это должно поддерживать вывод в том порядке, в котором вы их указали.

$Export = $Connections | Foreach-Object { Query -SqlConnection $_.SqlConnection -Data $_.UserConnection }
return $Export

Затем вы можете продолжить действия сценария два, как показано ниже. Я не уверен, что вам нужен отдельный.

foreach ($obj in $Export) {
    # Do stuff here.
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...