2013-02-15 22 views
5

Sono nuovo in PowerShell e ho bisogno di aiuto. Il mio primo script per il lavoro automatizza i nuovi utenti definiti nell'ambiente AD.PowerShell - combinazione di array

Una discarica CSV verrà eseguita una volta al giorno dal nostro sistema Peoplesoft. Io uso Import-CSV e creo 3 matrici (nuove, a termine ed elaborate).

Il problema che sto avendo è quello di combinare i 3 array una volta che faccio un giro tra tutti gli utenti e prova a rimetterlo nel file. Il codice si interrompe sulle linee $New += $Term. Credo che questo sia dovuto al fatto che nel mio file di test c'è solo 1 record di ogni tipo di utente (nuovo, termine ed elaborato) (lo so, aggiungo più utenti e hellip; impossibile. Questo potrebbe essere un risultato reale per qualsiasi giorno particolare). Di seguito è il mio codice di esempio:

#Get Credentials from user 
$c = Get-Credential 

#Get Date for $Term array population 
$e = Get-Date -format M/d/yyyy 

#Set file location and variable for said file 
$File = "c:\users\nmaddux\desktop\adduserstuff\test.csv" 

#Import record sets for New and Term users 
$New = @() 
$Term = @() 
$Procd = @() 
$New = Import-Csv $File | Where-Object { 
      $_.TermDate -eq "" -and $_.LastName -ne "" -and $_.Processdate -eq "" 
     } 
$Term = Import-Csv $File | Where-Object { 
      $_.TermDate -ne "" -and $_.Processdate -eq "" -and $_.TermDate -le $e 
     } 
$Procd = Import-Csv $File | Where-Object { $_.Processdate -ne "" } 

#Process both new and term users provided there are records to process for each 
If ($New -ne $NULL -and $Term -ne $NULL) { 
    # Some code to process users 
} 

$new += $term 
$new += $Procd 
$new | Export-Csv $file -NoTypeInformation -ErrorAction SilentlyContinue 

Così esporterà ma solo risultati parziali.

errore - Il richiamo del metodo non è riuscito perché [System.Management.Automation.PSObject] non contiene un metodo denominato "op_Addition".

+1

'$ Nuovo + = $ Term' E quella linea è dove ...? – aquinas

+0

Aggiunto il codice e la dichiarazione di errore ... mi scuso. – user2077056

risposta

11

Se Import-Csv restituisce solo 1 risultato, allora si è corretto che si supponga che la variabile NON sia un array, quindi la concatenazione avrà esito negativo. Questo non è cambiato dal fatto che hai pre-inizializzato le tue variabili con @(). In realtà, quel passaggio non è necessario.

Per forzare il risultato da trattare come una matrice, è possibile avvolgere l'intera riga Import-Csv in @() oppure eseguire un'operazione simile in seguito.

$new = @(Import-Csv $File | Where-Object {...}) 
# or 
$new = Import-Csv $File | Where-Object {...} 
$new = @($new) 
+0

Eccellente, grazie! Ci proverò. Nota a margine, ho provato a inviare tutto a un nuovo array ....ie '$ total = @()' $ totale + = $ nuovo $ totale + = $ termine Quindi esportare $ totale ha restituito tutti e tre gli utenti nel mio file di test. Perché funziona e non l'originale? – user2077056

+1

In questo caso si sta inizializzando '$ total' come array, quindi si esegue immediatamente un" plus-equal "su di esso. Quindi powershell sa che stai facendo un'operazione su array e agisce in modo appropriato. Nel tuo codice originale, inizializzi '$ new' come array, ma poi riassegnalo all'output di un cmdlet prima di fare i plus-equals. Se il cmdlet ha restituito solo 1 valore, powershell avrà cambiato '$ new' in una variabile scalare, e quindi più-uguali non ha senso. – latkin

+1

'$ a = @ ($ b) + @ ($ c)' ho risolto un problema simile per me. Grazie per l'utile risposta @latkin. – kevinmicke

0

È possibile anche applicare il tipo da typecasting variabile:

$array = @() 
$array = gci test.txt 
$array.GetType() 

[array]$array = @() 
$array = gci test.txt 
$array.GetType() 

IsPublic IsSerial Nome BaseType
-------- -------- --- - --------
true FileInfo System.IO.FileSystemInfo
true Object [] System.Array

1

Così si sta importando lo stesso CSV f ile 3 volte? non è meglio importarlo una volta e quindi impostare gli array per filtrarli "viste" di esso?

Un po 'come questo. Dovresti anche essere in grado di usare il valore "Conteggio" di ogni matrice per dire se sono stati restituiti 1 o più risultati.

#Get Credentials from user 
$c = Get-Credential 

#Get Date for $Term array population 
$e = Get-Date -format M/d/yyyy 

#Set file location and variable for said file 
$File = "c:\users\nmaddux\desktop\adduserstuff\test.csv" 

#Import record sets for New and Term users 
[array]$New 
[array]$Term 
[array]$Procd 

[array]$Import = Import-Csv $File 
[array]$New = $Import | ? {$_.TermDate -eq "" -and $_.LastName -ne "" -and $_.Processdate -eq ""} 
[array]$Term = $Import | ? {$_.TermDate -ne "" -and $_.Processdate -eq "" -and $_.TermDate -le $e} 
[array]$Procd = $Import | ? {$_.Processdate -ne ""} 

#Process both new and term users provided there are records to process for each 
if (($New.Count -gt 0) -and ($Term.Count -gt 0)) 
{ 
    # Some code to process users 
} 

$new += $term 
$new += $Procd 
$new | Export-Csv $file -NoTypeInformation -ErrorAction SilentlyContinue 
0

so che vengo in questa discussione in ritardo, ma per qualcun altro che viene avanti ... Dal momento che avete già definito $ nuovo come un array vuoto, quando si importa dal CSV che si desidera ADD l'output sull'array predefinito, non impostato uguale all'output di import-csv.

$new = @() 
$new += Import-Csv $File | Where-Object { 
      $_.TermDate -eq "" -and $_.LastName -ne "" -and $_.Processdate -eq "" 
     }