2014-09-02 3 views
0

Мне кажется, что, возможно, я пропускаю что-то простое здесь, но у меня возникают проблемы с циклом ForEach в PowerShell, который фактически возвращает все элементы, которые я ожидаю. У меня есть скрипт, который будет запрашивать базу данных Oracle и собирать базовый набор данных. После того, как это будет собрано, мне нужно будет выполнить некоторые изменения в том, что возвращается, и создать дополнительный бит информации (а не в настоящее время в скрипте).PowerShell ForEach loop возвращает только один результат

Что я делаю, это добавление данных в массив, а затем пытается использовать цикл ForEach для проверки каждого элемента в массиве и накачки данных из другого массива, который будет иметь новые свойства, которые мне нужно заполнить, на основе некоторых вычислений базового набора данных. То, что я возвращаю в переменную $ finaloutput, - это только одна строка данных (для примера, который я размещаю здесь, я просто ищу один номер отчета, равный CPOD-018, который содержит 5 из набора данных с различными другими свойствами заполненный, включая и sitename, который я заполняю, но все равно получаю только один результат).

Я попытался обойти это, используя вложенные операторы if в цикле ForEach вместо конвейера Where-Object, но получил те же результаты. Ниже приведена текущая версия скрипта, любая помощь будет с благодарностью оценена.

param(
    [parameter(mandatory=$True)]$username, 
    [parameter(mandatory=$True)]$password 
    ) 

# setup the finaloutput variable 
$finaloutput = New-Object psobject 

$finaloutput | Add-Member -MemberType NoteProperty -name ReportNumber -value NotSet 
$finaloutput | Add-Member -MemberType NoteProperty -name sitename -value NotSet 

# the connection string to be used by the OlEDB connection 
$connString = @" 
    Provider=OraOLEDB.Oracle;Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST="host.host.host")(PORT="1521")) 
    (CONNECT_DATA=(SERVICE_NAME="name.name.name")));User ID="$username";Password="$password" 
"@ 

# the query that will be used to gather data from Oracle 
$qry= @" 
    select VP_EXPECTED_DETAILS.REPORTNUMBER, VP_EXPECTED_DETAILS.SITE_NAME, VP_ACTUAL_FILENAME_DETAILS.FILE_NAME, VP_EXPECTED_DETAILS.MAX_EXPECTED_LOAD_TIME, VP_EXPECTED_DETAILS.EXPECTED_FREQUENCY, 
    VP_EXPECTED_DETAILS.DATE_TIMING, VP_EXPECTED_DETAILS.FREQUENCY_DAY, VP_EXPECTED_DETAILS.JOB_NO, 
    TO_CHAR(VP_ACTUAL_RPT_DETAILS.GEN_PARSE_IN,'YYYYMMDDHH24MISS') AS GEN_PARSE_IN, 
    TO_CHAR(VP_ACTUAL_RPT_DETAILS.GEN_PARSE_OUT,'YYYYMMDDHH24MISS') AS GEN_PARSE_OUT, 
    TO_CHAR(VP_ACTUAL_RPT_DETAILS.ETLLOADER_IN,'YYYYMMDDHH24MISS') AS ETLLOADER_IN, 
    TO_CHAR(VP_ACTUAL_RPT_DETAILS.ETLLOADER_OUT,'YYYYMMDDHH24MISS') AS ETLLOADER_OUT 

    from MONITOR.VP_EXPECTED_DETAILS 

    LEFT JOIN MONITOR.VP_ACTUAL_RPT_DETAILS on VP_EXPECTED_DETAILS.REPORTNUMBER = VP_ACTUAL_RPT_DETAILS.REPORTNUMBER and VP_EXPECTED_DETAILS.SITE_NAME = VP_ACTUAL_RPT_DETAILS.SITE_NAME 

    LEFT JOIN MONITOR.VP_ACTUAL_FILENAME_DETAILS on VP_ACTUAL_RPT_DETAILS.FNKEY = VP_ACTUAL_FILENAME_DETAILS.FNKEY where VP_EXPECTED_DETAILS.EXPECTED_FREQUENCY = 'DAILY' or 
    (VP_EXPECTED_DETAILS.EXPECTED_FREQUENCY = 'MONTHLY' AND VP_EXPECTED_DETAILS.FREQUENCY_DAY = EXTRACT(DAY from SYSDATE)) 
"@ 

# the function that will open the database connection and execute the query 
function Get-OLEDBData ($connectstring, $sql) { 
    $OLEDBConn = New-Object System.Data.OleDb.OleDbConnection($connectstring) 
    $OLEDBConn.open() 
    $readcmd = New-Object system.Data.OleDb.OleDbCommand($sql,$OLEDBConn) 
    $readcmd.CommandTimeout = '300' 
    $da = New-Object system.Data.OleDb.OleDbDataAdapter($readcmd) 
    $dt = New-Object System.Data.DataTable 
    [void]$da.fill($dt) 
    $OLEDBConn.close() 
    return $dt 
} 

# populate $output with the data from the Get-OLEDBData function 
$output = Get-OLEDBData $connString $qry 

# build the final output that will generate alerts 
ForEach ($lines in $output | Where-Object {$_.reportnumber -eq "CPOD-018"}) 
    { 
     $finaloutput.reportnumber = $lines.reportnumber 
     $finaloutput.sitename = $lines.SITE_NAME 
    } 

$finaloutput 
+0

try $ outputFiltered = $ output | Where-Object {$ _. Reportnumber -eq "CPOD-018"}) then: foreach ($ lines in $ output) и т. Д. – Jimbo

+0

Пока ваше предложение вернет мне правильный набор данных для ввода внутри $ outputfiltered , он не учитывает мою потребность в том, чтобы все еще проходить через каждый объект и выполнять действия над возвращаемыми данными. В конечном итоге мне нужно будет сделать одно из значений в массиве и установить значение даты/времени на основе значения для каждого элемента, который я буду использовать. Использование вашего предложения по-прежнему возвращает только один объект в переменной FinalOutput. – billhubb84

ответ

2

Похоже, что вы делаете неправильное создание объекта. Внутри цикла Еогеасп вы держите перезапись те же значения, а не добавление новых объектов

Он должен выглядеть следующим образом:

$FinalOutput = ForEach ($lines in $output | Where-Object {$_.reportnumber -eq "CPOD-018"}) 
    { 
     $Prop = @{ 
     'reportnumber' = $lines.reportnumber 
     'sitename' = $lines.SITE_NAME 
     } 
     New-Object -Type PSObject -Property $Prop 
    } 
$FinalOutput 

Вы должны закомментировать finaloutput линии в начале вашего скрипта.

+0

Спасибо большое, я знал, что это будет что-то простое, что я пропал без вести, ваш совет вернул меня в путь, очень ценится! – billhubb84

+0

Удивительный, рад, что я мог бы помочь. –

Смежные вопросы