Question Pb avec filtre dans une variable
- Régis LOUIS
- Auteur du sujet
- Hors Ligne
- Nouveau membre
Réduire
Plus d'informations
- Messages : 14
- Remerciements reçus 0
il y a 13 ans 9 mois #7377
par Régis LOUIS
Pb avec filtre dans une variable a été créé par Régis LOUIS
Bonjour,
Je construis un filtre dans une variable parce que par défaut, je ne connais pas le nom des dossiers à exclure lorsque je fais un get-childitem.
La construction de la ligne qui va filtrer se fait par un get-content d'un fichier txt contenant les dossiers à exclure.
[code:1]$Fichier_Exclusions = Get-Content c:\WINDOWS\system32\WindowsPowerShell\v1.0\exclusion.txt
[string]$Exclusion_Parameter = $null
foreach ($line in $Fichier_Exclusions)
{
[string]$Traitement = $Path_App_Files + $line
$Traitement = $Traitement -replace \"\\\",\"\\\"
If (!($Exclusion_Parameter))
{
$Exclusion_Parameter = $Exclusion_Parameter + \"`$_.fullname -notmatch \" + $Traitement
}
Else
{
$Exclusion_Parameter = $Exclusion_Parameter + \" -and `$_.fullname -notmatch \" + $Traitement
}
}
$Exclusion_Parameter = $Exclusion_Parameter + \" -and `$_.PSIsContainer -notmatch `$true\"[/code:1]
Jusque là ça fonctionne bien. Il me contruit bien mon filtre comme je le souhaite
C'est ensuite que cela se complique
[code:1]Get-ChildItem -Path $Path_App_Files *.* -include * -Recurse | where {$Exclusion_Parameter} | select-object Name,LastWriteTime,Directory | Export-Csv $PathLog\Liste_Files.csv -NoTypeInformation -Encoding UTF8
[/code:1]
Le contenu de variable $Exclusion_Parameter n'est pas pris en compte et je n'ai pas de message d'erreur.
La syntaxe suivante fonctionne mais m'oblige à fixer les dossiers à exclure que je ne peux connaître à l'avance
[code:1]Get-ChildItem -Path $Path_App_Files *.* -include * -Recurse | where {$_.fullname -notmatch $Path_Exclude1 -and $_.fullname -notmatch $Path_Exclude2 -and $_.PSIsContainer -notmatch $true} | select-object Name,LastWriteTime,Directory | Export-Csv $PathLog\Liste_Files.csv -NoTypeInformation -Encoding UTF8
[/code:1]
Comment faire pour que le contenu de ma variable $Exclusion_Parameter soit prise en compte par la cmdlet Where-Object ?
Je construis un filtre dans une variable parce que par défaut, je ne connais pas le nom des dossiers à exclure lorsque je fais un get-childitem.
La construction de la ligne qui va filtrer se fait par un get-content d'un fichier txt contenant les dossiers à exclure.
[code:1]$Fichier_Exclusions = Get-Content c:\WINDOWS\system32\WindowsPowerShell\v1.0\exclusion.txt
[string]$Exclusion_Parameter = $null
foreach ($line in $Fichier_Exclusions)
{
[string]$Traitement = $Path_App_Files + $line
$Traitement = $Traitement -replace \"\\\",\"\\\"
If (!($Exclusion_Parameter))
{
$Exclusion_Parameter = $Exclusion_Parameter + \"`$_.fullname -notmatch \" + $Traitement
}
Else
{
$Exclusion_Parameter = $Exclusion_Parameter + \" -and `$_.fullname -notmatch \" + $Traitement
}
}
$Exclusion_Parameter = $Exclusion_Parameter + \" -and `$_.PSIsContainer -notmatch `$true\"[/code:1]
Jusque là ça fonctionne bien. Il me contruit bien mon filtre comme je le souhaite
C'est ensuite que cela se complique
[code:1]Get-ChildItem -Path $Path_App_Files *.* -include * -Recurse | where {$Exclusion_Parameter} | select-object Name,LastWriteTime,Directory | Export-Csv $PathLog\Liste_Files.csv -NoTypeInformation -Encoding UTF8
[/code:1]
Le contenu de variable $Exclusion_Parameter n'est pas pris en compte et je n'ai pas de message d'erreur.
La syntaxe suivante fonctionne mais m'oblige à fixer les dossiers à exclure que je ne peux connaître à l'avance
[code:1]Get-ChildItem -Path $Path_App_Files *.* -include * -Recurse | where {$_.fullname -notmatch $Path_Exclude1 -and $_.fullname -notmatch $Path_Exclude2 -and $_.PSIsContainer -notmatch $true} | select-object Name,LastWriteTime,Directory | Export-Csv $PathLog\Liste_Files.csv -NoTypeInformation -Encoding UTF8
[/code:1]
Comment faire pour que le contenu de ma variable $Exclusion_Parameter soit prise en compte par la cmdlet Where-Object ?
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Hors Ligne
- Modérateur
Réduire
Plus d'informations
- Messages : 6302
- Remerciements reçus 68
il y a 13 ans 9 mois #7378
par Laurent Dardenne
Tutoriels PowerShell
Réponse de Laurent Dardenne sur le sujet Re:Pb avec filtre dans une variable
Salut,
rnglouis écrit:
[code:1]
{$Exclusion_Parameter}
#$Exclusion_Parameter
&{$Exclusion_Parameter}
#$_.fullname -notmatch test.txt -and $_.fullname -notmatch cou pure.dat -and
#$_.PSIsContainer -notmatch $true -and $_.fullname -notmatch test.txt -and $_.fullname -notmatch cou pure.dat
[/code:1]
Tu recherches à substituer le contenu de la variable, mais tu ne fais que réémettre l'objet reçu car \"ton filtre\" n'est pas exécuté en tant que code :
[code:1]
$Exclusion_Parameter=\"Contenu renseigné\"
1|where {$Exclusion_Parameter}|gm
# TypeName: System.Int32
#...
$Exclusion_Parameter=$null
1|where {$Exclusion_Parameter}|gm
#Get-Member : Aucun objet n'a été spécifié à l'applet de commande get-member.
$Exclusion_Parameter=$false
1|where {$Exclusion_Parameter}|Write-host -fore green
#rien
$Exclusion_Parameter=$true
1|where {$Exclusion_Parameter}|Write-host -fore green
#1
$Exclusion_Parameter=$null
1|where {$Exclusion_Parameter}|Write-host -fore green
#rien
$Exclusion_Parameter=\"Contenu renseigné\"
1|where {$Exclusion_Parameter}|Write-host -fore green
#1
[/code:1]
Tu dois donc préciser ce que tu veux faire de la variable, PowerShell ne peux pas le deviner.
Avec cette approche tu dois donc construire le filtre ET le code d'interrogation.
rnglouis écrit:
rnglouis écrit:
[code:1]
#filtre les objets de type integer
$Exclusion_Parameter='$_ -is [int]'
$Filtre=$ExecutionContext.InvokeCommand.NewScriptBlock($Exclusion_Parameter)
\"A\",1| Where $Filtre
#renvoi seulement l'objet, l'entier, 1
[/code:1]
Ensuite l'opérateur -notmatch est dédié aux expressions régulières, donc au type string, mais ne concerne pas le test de boolean :
[code:1]
`$_.PSIsContainer -notmatch `$true\"
#ceci suffit
-and `$_.PSIsContainer -and ...
[/code:1]
Enfin tu devrais placer tes noms de fichiers entre guillemets : \"c:\program file\test.txt\", ce qui t'éviteras qq suprises...
Tu peux aussi consulter ce post qui à trait à la construction de filtre dynamique.<br><br>Message édité par: Laurent Dardenne, à: 13/07/10 14:38
rnglouis écrit:
Si, mais il ne fait pas ce que tu veux :Le contenu de variable $Exclusion_Parameter n'est pas pris en compte et je n'ai pas de message d'erreur.
[code:1]
{$Exclusion_Parameter}
#$Exclusion_Parameter
&{$Exclusion_Parameter}
#$_.fullname -notmatch test.txt -and $_.fullname -notmatch cou pure.dat -and
#$_.PSIsContainer -notmatch $true -and $_.fullname -notmatch test.txt -and $_.fullname -notmatch cou pure.dat
[/code:1]
Tu recherches à substituer le contenu de la variable, mais tu ne fais que réémettre l'objet reçu car \"ton filtre\" n'est pas exécuté en tant que code :
[code:1]
$Exclusion_Parameter=\"Contenu renseigné\"
1|where {$Exclusion_Parameter}|gm
# TypeName: System.Int32
#...
$Exclusion_Parameter=$null
1|where {$Exclusion_Parameter}|gm
#Get-Member : Aucun objet n'a été spécifié à l'applet de commande get-member.
$Exclusion_Parameter=$false
1|where {$Exclusion_Parameter}|Write-host -fore green
#rien
$Exclusion_Parameter=$true
1|where {$Exclusion_Parameter}|Write-host -fore green
#1
$Exclusion_Parameter=$null
1|where {$Exclusion_Parameter}|Write-host -fore green
#rien
$Exclusion_Parameter=\"Contenu renseigné\"
1|where {$Exclusion_Parameter}|Write-host -fore green
#1
[/code:1]
Tu dois donc préciser ce que tu veux faire de la variable, PowerShell ne peux pas le deviner.
Avec cette approche tu dois donc construire le filtre ET le code d'interrogation.
rnglouis écrit:
Tu as la réponse ici :Comment faire pour que le contenu de ma variable $Exclusion_Parameter soit prise en compte par la cmdlet Where-Object ?
rnglouis écrit:
Ton code contruit une string, si tu construis un scriptblock la suite est bien plus simple :Je construis un filtre dans une variable
[code:1]
#filtre les objets de type integer
$Exclusion_Parameter='$_ -is [int]'
$Filtre=$ExecutionContext.InvokeCommand.NewScriptBlock($Exclusion_Parameter)
\"A\",1| Where $Filtre
#renvoi seulement l'objet, l'entier, 1
[/code:1]
Ensuite l'opérateur -notmatch est dédié aux expressions régulières, donc au type string, mais ne concerne pas le test de boolean :
[code:1]
`$_.PSIsContainer -notmatch `$true\"
#ceci suffit
-and `$_.PSIsContainer -and ...
[/code:1]
Enfin tu devrais placer tes noms de fichiers entre guillemets : \"c:\program file\test.txt\", ce qui t'éviteras qq suprises...
Tu peux aussi consulter ce post qui à trait à la construction de filtre dynamique.<br><br>Message édité par: Laurent Dardenne, à: 13/07/10 14:38
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Régis LOUIS
- Auteur du sujet
- Hors Ligne
- Nouveau membre
Réduire
Plus d'informations
- Messages : 14
- Remerciements reçus 0
il y a 13 ans 9 mois #7379
par Régis LOUIS
Réponse de Régis LOUIS sur le sujet Re:Pb avec filtre dans une variable
Merci beaucoup Laurent pour ton aide
En effet je ne savais pas comment faire pour que ma variable soit comprise comme un scriptblock
il me manquait cette ligne :
[code:1]$Filtre=$ExecutionContext.InvokeCommand.NewScriptBlock($Exclusion_Parameter)
[/code:1]
et les guillemets.
Par contre cette syntaxe ne liste que les dossiers
[code:1]-and `$_.PSIsContainer[/code:1]
Or ce que je recherche c'est l'exclusion des dossiers. Je ne cherche que la liste de tous les fichiers.
La syntaxe a priori idéale puisque la propriété est booléenne est
[code:1]-and !(`$_.PSIsContainer)[/code:1]
Confirmes tu ?<br><br>Message édité par: rnglouis, à: 13/07/10 15:50
En effet je ne savais pas comment faire pour que ma variable soit comprise comme un scriptblock
il me manquait cette ligne :
[code:1]$Filtre=$ExecutionContext.InvokeCommand.NewScriptBlock($Exclusion_Parameter)
[/code:1]
et les guillemets.
Par contre cette syntaxe ne liste que les dossiers
[code:1]-and `$_.PSIsContainer[/code:1]
Or ce que je recherche c'est l'exclusion des dossiers. Je ne cherche que la liste de tous les fichiers.
La syntaxe a priori idéale puisque la propriété est booléenne est
[code:1]-and !(`$_.PSIsContainer)[/code:1]
Confirmes tu ?<br><br>Message édité par: rnglouis, à: 13/07/10 15:50
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Hors Ligne
- Modérateur
Réduire
Plus d'informations
- Messages : 6302
- Remerciements reçus 68
il y a 13 ans 9 mois #7380
par Laurent Dardenne
Tutoriels PowerShell
Réponse de Laurent Dardenne sur le sujet Re:Pb avec filtre dans une variable
rnglouis écrit:
[code:1]
[boolean] $IsPsContainer=$true
if ($IsPsContainer) {\"Le test réussi\"} else {\"le test échoue\"}
#Le test réussi
$IsPsContainer=$false
if ($IsPsContainer) {\"Le test réussi\"} else {\"le test échoue\"}
#le test échoue
[/code:1]
C'est une facilité d'écriture, on peut écrire comme ceci :
[code:1]
$IsPsContainer=$true
if ($IsPsContainer -eq $true) {\"Le test réussi\"} else {\"le test échoue\"}
#Le test réussi
[/code:1]
On peut revoir le comportement précisé dans le post précédent :
[code:1]
$Exclusion_Parameter=\"Contenu renseigné\"
if ($Exclusion_Parameter) {\"Le test réussi\"} else {\"le test échoue\"}
#Le test réussi
$Exclusion_Parameter=$null
if ($Exclusion_Parameter) {\"Le test réussi\"} else {\"le test échoue\"}
#le test échoue
[/code:1]
Si le contenu de la variable est à $null alors le test échoue, c'est un comportement à connaître.
Si on manipule des entiers:
[code:1]
$Parameter=3
if ($Parameter) {\"Le test réussi\"} else {\"le test échoue\"}
#Le test réussi
$Parameter=0
if ($Parameter) {\"Le test réussi\"} else {\"le test échoue\"}
#le test échoue, car [int]$false = 0
[/code:1]
Ces comportements sont dus à la conversion en cas d'absence d'opérateur:
[code:1]
#$Parameter=$null
$Parameter -as [boolean]
#False
$Parameter=\"Test\"
$Parameter -as [boolean]
#True
$Parameter=0
$Parameter -as [boolean]
#False
$Parameter=3
$Parameter -as [boolean]
#True
[/code:1]
Mais si on précise un opérateur, on effectue alors un 'vrai test booléen' :
[code:1]
$Parameter=3
if ($Parameter -eq $true) {\"Le test réussi\"} else {\"le test échoue\"}
#le test échoue
$Parameter=$null
if ($Parameter -eq $true) {\"Le test réussi\"} else {\"le test échoue\"}
#le test échoue
$Parameter=\"test\"
if ($Parameter -eq $true) {\"Le test réussi\"} else {\"le test échoue\"}
#le test échoue
$Parameter=$null
if ($Parameter -eq $true) {\"Le test réussi\"} else {\"le test échoue\"}
#le test échoue, idem pour $Parameter=\"\"
$Parameter=0
if ($Parameter -eq $true) {\"Le test réussi\"} else {\"le test échoue\"}
#le test échoue
[/code:1]
Pour résumé :
- si ta variable est typée en boolean, tu peux ne pas préciser d'opérateur.
- si ta variable n'est pas typée en boolean, tu dois préciser un opérateur pour éviter des effets de bords et faciliter la relecture.
En espérant ne pas t'avoir embrouillé.<br><br>Message édité par: Laurent Dardenne, à: 25/07/10 18:44
Le plus souvent dans les langages informatique, l'usage d'un booléen (seules deux valeurs sont possibles) dans un test ne nécessite pas de préciser d'opérateur d'égalité :Par contre je n'ai pas compris si la syntaxe
[code:1]-and `$_.PSIsContainer[/code:1]
[code:1]
[boolean] $IsPsContainer=$true
if ($IsPsContainer) {\"Le test réussi\"} else {\"le test échoue\"}
#Le test réussi
$IsPsContainer=$false
if ($IsPsContainer) {\"Le test réussi\"} else {\"le test échoue\"}
#le test échoue
[/code:1]
C'est une facilité d'écriture, on peut écrire comme ceci :
[code:1]
$IsPsContainer=$true
if ($IsPsContainer -eq $true) {\"Le test réussi\"} else {\"le test échoue\"}
#Le test réussi
[/code:1]
On peut revoir le comportement précisé dans le post précédent :
[code:1]
$Exclusion_Parameter=\"Contenu renseigné\"
if ($Exclusion_Parameter) {\"Le test réussi\"} else {\"le test échoue\"}
#Le test réussi
$Exclusion_Parameter=$null
if ($Exclusion_Parameter) {\"Le test réussi\"} else {\"le test échoue\"}
#le test échoue
[/code:1]
Si le contenu de la variable est à $null alors le test échoue, c'est un comportement à connaître.
Si on manipule des entiers:
[code:1]
$Parameter=3
if ($Parameter) {\"Le test réussi\"} else {\"le test échoue\"}
#Le test réussi
$Parameter=0
if ($Parameter) {\"Le test réussi\"} else {\"le test échoue\"}
#le test échoue, car [int]$false = 0
[/code:1]
Ces comportements sont dus à la conversion en cas d'absence d'opérateur:
[code:1]
#$Parameter=$null
$Parameter -as [boolean]
#False
$Parameter=\"Test\"
$Parameter -as [boolean]
#True
$Parameter=0
$Parameter -as [boolean]
#False
$Parameter=3
$Parameter -as [boolean]
#True
[/code:1]
Mais si on précise un opérateur, on effectue alors un 'vrai test booléen' :
[code:1]
$Parameter=3
if ($Parameter -eq $true) {\"Le test réussi\"} else {\"le test échoue\"}
#le test échoue
$Parameter=$null
if ($Parameter -eq $true) {\"Le test réussi\"} else {\"le test échoue\"}
#le test échoue
$Parameter=\"test\"
if ($Parameter -eq $true) {\"Le test réussi\"} else {\"le test échoue\"}
#le test échoue
$Parameter=$null
if ($Parameter -eq $true) {\"Le test réussi\"} else {\"le test échoue\"}
#le test échoue, idem pour $Parameter=\"\"
$Parameter=0
if ($Parameter -eq $true) {\"Le test réussi\"} else {\"le test échoue\"}
#le test échoue
[/code:1]
Pour résumé :
- si ta variable est typée en boolean, tu peux ne pas préciser d'opérateur.
- si ta variable n'est pas typée en boolean, tu dois préciser un opérateur pour éviter des effets de bords et faciliter la relecture.
En espérant ne pas t'avoir embrouillé.<br><br>Message édité par: Laurent Dardenne, à: 25/07/10 18:44
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Hors Ligne
- Modérateur
Réduire
Plus d'informations
- Messages : 6302
- Remerciements reçus 68
il y a 13 ans 8 mois #7454
par Laurent Dardenne
Tutoriels PowerShell
Réponse de Laurent Dardenne sur le sujet Re:Pb avec filtre dans une variable
J'ajoute ceci pour garder une trace :
[code:1]
$Parameter=3
if ($true -eq $Parameter) {\"Le test réussi\"} else {\"le test échoue\"}
#le test réussi
$Parameter=$null
if ($true -eq $Parameter) {\"Le test réussi\"} else {\"le test échoue\"}
#le test échoue
$Parameter=\"test\"
if ($true -eq $Parameter) {\"Le test réussi\"} else {\"le test échoue\"}
#le test réussi
$Parameter=$null
if ($true -eq $Parameter) {\"Le test réussi\"} else {\"le test échoue\"}
#le test échoue, idem pour $Parameter=\"\"
$Parameter=0
if ($true -eq $Parameter) {\"Le test réussi\"} else {\"le test échoue\"}
#le test échoue
[/code:1]
Pour faciliter les choses, selon que la valeur à convertir est à gauche ou à droite de l'opérateur, le résultat différe pour
$Parameter=3 et $Parameter=\"test\"
Les syntaxes suivantes sont donc autorisées :
[code:1]$F=dir C:\Temp\UnFichierDeTest.Txt
$F.IsReadOnly
$F.isReadOnly=\" f sd\"
$F.IsReadOnly
$F.isReadOnly=$null
$F.IsReadOnly
$f.IsReadOnly=7
$f.IsReadOnly[/code:1]
Cela ne pose pas de pb !!!
[edit]
From PowerShell.com
When you compare version strings, PowerShell will use alphanumeric algorithms, which may lead to confusing results:
[code:1]'3.4.22.12' -gt '22.1.4.34'
True
[/code:1]
You should convert the strings to a System.Version type to compare version strings right. In fact, converting the left hand value is enough because PowerShell automatically converts the right hand value to the same type:
[code:1][System.Version] '3.4.22.12' -gt '22.1.4.34'
False
[/code:1]
Message édité par: Laurent Dardenne, à: 1/09/10 16:46<br><br>Message édité par: Laurent Dardenne, à: 1/09/10 16:46
[code:1]
$Parameter=3
if ($true -eq $Parameter) {\"Le test réussi\"} else {\"le test échoue\"}
#le test réussi
$Parameter=$null
if ($true -eq $Parameter) {\"Le test réussi\"} else {\"le test échoue\"}
#le test échoue
$Parameter=\"test\"
if ($true -eq $Parameter) {\"Le test réussi\"} else {\"le test échoue\"}
#le test réussi
$Parameter=$null
if ($true -eq $Parameter) {\"Le test réussi\"} else {\"le test échoue\"}
#le test échoue, idem pour $Parameter=\"\"
$Parameter=0
if ($true -eq $Parameter) {\"Le test réussi\"} else {\"le test échoue\"}
#le test échoue
[/code:1]
Pour faciliter les choses, selon que la valeur à convertir est à gauche ou à droite de l'opérateur, le résultat différe pour
$Parameter=3 et $Parameter=\"test\"
Les syntaxes suivantes sont donc autorisées :
[code:1]$F=dir C:\Temp\UnFichierDeTest.Txt
$F.IsReadOnly
$F.isReadOnly=\" f sd\"
$F.IsReadOnly
$F.isReadOnly=$null
$F.IsReadOnly
$f.IsReadOnly=7
$f.IsReadOnly[/code:1]
Cela ne pose pas de pb !!!
[edit]
From PowerShell.com
When you compare version strings, PowerShell will use alphanumeric algorithms, which may lead to confusing results:
[code:1]'3.4.22.12' -gt '22.1.4.34'
True
[/code:1]
You should convert the strings to a System.Version type to compare version strings right. In fact, converting the left hand value is enough because PowerShell automatically converts the right hand value to the same type:
[code:1][System.Version] '3.4.22.12' -gt '22.1.4.34'
False
[/code:1]
Message édité par: Laurent Dardenne, à: 1/09/10 16:46<br><br>Message édité par: Laurent Dardenne, à: 1/09/10 16:46
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
Temps de génération de la page : 0.078 secondes
- Vous êtes ici :
- Accueil
- forum
- PowerShell
- Entraide pour les initiés
- Pb avec filtre dans une variable