web-dev-qa-db-fra.com

Multiple-and-or dans PowerShell, instruction Where-Object

PS H:\> Invoke-Command -computername SERVERNAME { Get-ChildItem -path E:\dfsroots\datastore2\public} | Where-Object {{ $_.e
xtension-match "xls" -or $_.extension-match "xlk" } -and  { $_.creationtime -ge "06/01/2014"}}

Ci-dessus, mon exemple de code. J'essaie d'exécuter à distance ce code PowerShell sur mon serveur de fichiers et de le renvoyer tous les fichiers .xls et .xlk dont la date de création est au plus tard le 01/06/2014. Lorsque j'exécute ce code, il commence à cracher tous les dossiers de cet emplacement distant. Si je compare seulement deux choses comme celle-ci:

PS H:\> Invoke-Command -computername SERVERNAME { Get-ChildItem -path E:\dfsroots\datastore2\public} | Where-Object { $_.extension-match "xls" -and  $_.creationtime -ge "06/01/2014"}

Seuls les fichiers xls créés à cette date ou après sont affichés. Que se passe t-il ici? Dois-je utiliser autre chose que nid -and et -or déclarations?

28
Winski Tech

En encapsulant vos comparaisons dans {} dans votre premier exemple, vous créez ScriptBlocks; de sorte que l'interprète PowerShell le considère comme Where-Object { <ScriptBlock> -and <ScriptBlock> }. Depuis le -and l'opérateur opère sur les valeurs booléennes, PowerShell convertit les ScriptBlocks en valeurs booléennes. Dans PowerShell, tout ce qui n'est pas vide, zéro ou null est vrai. La déclaration ressemble alors à Where-Object { $true -and $true } qui est toujours vrai.

À la place d'utiliser {}, utilisez des parenthèses ().

Aussi, vous voulez utiliser -eq au lieu de -match puisque match utilise regex et sera vrai si le motif se trouve n’importe où dans la chaîne (try: 'xlsx' -match 'xls').

Invoke-Command -computername SERVERNAME { 
    Get-ChildItem -path E:\dfsroots\datastore2\public | 
        Where-Object {($_.extension -eq ".xls" -or $_.extension -eq ".xlk") -and ($_.creationtime -ge "06/01/2014")}
}

Une meilleure option consiste à filtrer les extensions à la Get-ChildItem commande.

Invoke-Command -computername SERVERNAME { 
    Get-ChildItem -path E:\dfsroots\datastore2\public\* -Include *.xls, *.xlk | 
        Where-Object {$_.creationtime -ge "06/01/2014"}
}
40
Rynant

Vous utilisez des accolades courbes lorsque vous devriez utiliser des parenthèses.

Une instruction where est conservée à l'intérieur d'un scriptblock, qui est défini à l'aide de caractères courbes { }. Pour isoler/boucler vos tests, vous devez utiliser des parenthèses ().

Je suggérerais également d'essayer de faire le filtrage sur l'ordinateur distant. Essayer:

Invoke-Command -computername SERVERNAME {
    Get-ChildItem -path E:\dfsroots\datastore2\public |
    Where-Object { ($_.extension -eq "xls" -or $_.extension -eq "xlk") -and $_.creationtime -ge "06/01/2014" }
}
4
Frode F.