Question
[TechEd] PS v4 : DSC in Windows 2012 R2
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
- Messages : 6300
- Remerciements reçus 68
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Walid Toumi
- Hors Ligne
- Nouveau membre
- Messages : 3
- Remerciements reçus 0
une petite amélioration de la méthode de filtre WHERE et son implémentation en v2:
www.developpez.net/forums/d1365449/gener...-avec-powershell-20/
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
- Messages : 6300
- Remerciements reçus 68
il y a plusieurs copie de ton post.
J'ai un doute sur cette implémentation, car tu ajoutes du code pour finalement appeler :
[code:1]
$this | Where-Object -Filter $sb
[/code:1]
Une extension de méthode C# est peut être à privilégier ?
Une alternative dans ta regex peut améliorer les perfs, à vérifier.
Je n'ai pas désassembler le code de la v4 de PS, mais il est probable que cette version propose cette syntaxe sur les types implémentant l'interface IEnumerable et pas seulement sur System.Array.
La limite d'ETS est qu'elle ne permet pas d'adresser des interfaces ni des classes génériques. Pour ces dernières, on doit créer un fichier par classe
Dans ton exemple il manque le code d'appel :
[code:1]
Update-TypeData C:\Temp\WhereType.ps1xml
[/code:1]
PSitem n'est pas documenté.
L'usage d'une string simple quotte évite, je pense, le pb de la substitution, là où un scriptblock peut l'éviter, car le parseur n’interprète pas son contenu.
Et enfin ceci fonctionne :
[code:1]
(1..10).Where('PSitem -gt 5 -and (PSitem -band 1)')
[/code:1]
mais pas cela :
[code:1]
(get-process).Where('PSitem.Name -like ''p*'' ')
(get-process).Where('$_.Name -like ''p*'' ')
# code OK
#get-process | Where {$_.Name -like 'p*'}
[/code:1]<br><br>Message édité par: Laurent Dardenne, à: 29/07/13 16:32
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
- Messages : 6300
- Remerciements reçus 68
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
- Messages : 6300
- Remerciements reçus 68
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Walid Toumi
- Hors Ligne
- Nouveau membre
- Messages : 3
- Remerciements reçus 0
il y a plusieurs copies de ton post
je n'ai pas trouvé le boutton supprimer pour effacer les copies.
j'ai un doute sur cette implementation, car au final tu ajoutes du code pour finalement appeler
j'ai voulu juste améliorer l'extension de la fonction filtre de la V4 qui a en réalité le même code d'appel, et voulu surtout l'implementé en v2.
une extension de methode c# est peut etre a privilégier ?
tout a fait d'accord, ne serai-ce que pour améliorer les performances.
une alternative dans ta regex peux améliorer les perfs. a verifier
En utilisant .NET directement l'execution du code sera plus rapide, c'est pour cette dernière raison que j'ai opter pour l'operateur match au lieu de la cmdlet select-string.
..il est probable que cette version propose cette syntaxe sur les types implémentant l'interface IEnumerable et pas seulement sur System.Array
oui, et pas seulement V4 mais V3 aussi.
dans ton exemple il manque le code d'appel
j'aurais du l'écrire mais je me suis dit que la mise a jour du fichier de configuration passe impérativement, en V2, par update-typeData donc..
PSItem n'est pas documenté
c'est l'objet en cours passer par le pipeline, en d'autres termes \"$_\"
L'usage d'une string simple quotte évite, je pense, le pb de la substitution, là où un scriptblock peut l'éviter, car le parseur n’interprète pas son contenu.
il vaux mieux utiliser cette syntaxe pour éviter les problèmes d'ordres syntaxiques:
[code:1]
.where(guillemet|expression avec apostrophe ou pas |guillemet)
[/code:1]
donc pour être plus concret:
[code:1]
(get-process).Where(\"Name -like 'p*'\"«»)
[/code:1]
sauf si notre expression contient une variable, il faut donc retardé l'execution de cette variable dans le scriptblock en utilisant des apostrophes:
[code:1]
(get-process).Where('$true')
[/code:1]
dans ce code j'ai enlever le '$_' car il est changé par la proprieté PSItem et aussi j'ai enlevé le PSItem car on peux utiliser ses propriétés directement dans V2 comme en V3 et en V4, si on utilise l'objet PSItem il vaux mieux l'utiliser sans propriétés par contre si on utilise les propriétés directement on peux appeler ses 'sous-propriétés'.
[code:1]
(get-process).Where(\"Name.Length -gt 4 -and Name.substring(0,1) -eq 's'\"«»)
[/code:1]
et non pas:
[code:1]
(get-process).Where(\"PSItem.Name.Length -gt 4 -and PSItem.Name.substring(0,1) -eq 's'\"«»)
[/code:1]
on peux utiliser PSItem ainsi:
[code:1]
@(\"hello world\",\"bien\"«»).Where(\"PSItem -like 'h*'\"«»)
[/code:1]
et on peux aussi l'utiliser ainsi si on utilise une methode de l'objet:
[code:1]
$wmi = get-wmiobject win32_Process
$wmi.Where(\"PSItem.getowner().user -like '$env:username'\"«»)|%{$_.name}
[/code:1]
voici une petite amélioration du filtre:
[code:1]
<?xml version=\"1.0\" encoding=\"utf-8\" ?>
<Types>
<Type>
<Name>System.Array</Name>
<Members>
<ScriptMethod>
<Name>Where</Name>
<Script>
$arg = $args[0] -as [String]
$members = ($this |gm -Type *property |select -Unique -Expand name) +'PSItem'
$members | foreach {
if($arg -match \"\b$_\b\"«») {
if($Matches[0] -eq 'PSItem')
{ $arg=$arg -replace \"(?<= |^)$_\b\",'$$_'
}
else
{ $arg=$arg -replace \"(?<= |^)$_\b\",'$$_.$0'
}
}
}
$sb=$ExecutionContext.InvokeCommand.NewScriptBlock($arg)
$this | Where-Object -Filter $sb
</Script>
</ScriptMethod>
</Members>
</Type>
</Types>
[/code:1]
maintenant, on peux utiliser une syntaxe du genre:
[code:1]
(get-process).Where(\"PSItem.Name.Length -gt 4 -and PSItem.Name.substring(0,1) -eq 's'\"«»)
[/code:1]
Connexion ou Créer un compte pour participer à la conversation.
- Vous êtes ici :
- Accueil
- forum
- PowerShell
- Discussions générales
- [TechEd] PS v4 : DSC in Windows 2012 R2