Question Re:[fonction] New-PSCustomObjectFunction (Dynamisme)

Plus d'informations
il y a 11 ans 11 mois #12943 par Laurent Dardenne
Cette fonction permet de créer une fonction génèrant un objet personnalisé simple.
La fonction générée contient une clause Param, chaque paramètre est obligatoire, n'est pas typé et déclare une position, celle déclarée sur la ligne d'appel.
[code:1]
Function New-PSCustomObjectFunction {
#crée une fonction génèrant un objet personnalisé simple
#tous ses paramètres sont obligatoires et ne sont pas typé
#
# Par défaut génère du code sans la signature du mot clé Function
# La paramètre -FILE génére du code avec la signature du mot clé Function
param(
[Parameter(Mandatory=$true,position=0)]
[ValidateNotNullOrEmpty()]
$Noun,
[Parameter(Mandatory=$true,position=1)]
[ValidateNotNullOrEmpty()]
[String[]]$Parameters,
[switch] $File
)

$Borne=$Parameters.count-1
$code=@\"
$(if ($File) {\"Function New-$Noun{\"})
param(
$(For ($I=0;$I -le $Borne;$I++)
{ $Name=$Parameters[$I]
@\"
`t [Parameter(Mandatory=`$True,position=$I)]
`t`$${Name}$(if ($I -Ne $borne) {\",`r`n\"})
\"@
}
)
)
#Les paramétres liés définissent aussi les propriétés de l'objet
`$O=New-Object PSObject -Property `$PSBoundParameters
`$O.PsObject.TypeNames.Insert(0,\"$Noun\"«»)
`$O

$(if ($File) {\"}# New-$Noun\"})
\"@
$Code
}#New-PSCustomObjectFunction
[/code:1]
L'appel suivant :
[code:1]
$Name=\"ParsingDirective\"
New-PSCustomObjectFunction $Name 'Name','Line' | Set-Item Function:\"New-$Name\" -Force
[/code:1]
génére le code suivant:
[code:1]
param(
[Parameter(Mandatory=$True,position=0)]
$Name,
[Parameter(Mandatory=$True,position=1)]
$Line
)
#Les paramétres liés définissent aussi les propriétés de l'objet
$O=New-Object PSObject -Property $PSBoundParameters
$O.PsObject.TypeNames.Insert(0,\"ParsingDirective\"«»)
$O|Add-Member ScriptMethod ToString {'{0}:{1}' -F $this.Name,$this.Line} -Force -Passthru
[/code:1]
Celui-ci peut être directement utilisé lors de la création d'une fonction à l'aide du provider :
[code:1]
$Name=\"ParsingDirective\"
New-PSCustomObjectFunction $Name 'Name','Line' | Set-Item Function:\"New-$Name\" -Force
$o=New-ParsingDirective 'Debug' '10'
$o
$o.psobject.TypeNames
[/code:1]
On peut vouloir créer une fonction avec la déclaration complète :
[code:1]
$Code=New-PSCustomObjectFunction 'ParsingDirective' 'Name','Line' -File
$Code|
Set-Content C:\Temp\New-ParsingDirective.ps1
Type C:\Temp\New-ParsingDirective.ps1
[/code:1]
Une possible simplification de la saisie :
[code:1]
Function ql {$args}
New-PSCustomObjectFunction 'Test' (ql QL avec une fonction comportant de nombreux paramètres facilite la saisie) -File
[/code:1]

Notez l'usage de la variable automatique $PSBoundParameters lors de la création de l'objet personnalisé :
[code:1]
New-Object PSObject -Property $PSBoundParameters
[/code:1]
Ainsi on propage facilement tous les paramètres et leurs valeur, car $PSBoundParameters est une hashtable. D'où la déclaration de paramètres obligatoires.

[edit]
Une nouvelle version, créant des membres en lecture seule, est disponible ici <br><br>Message édité par: Laurent Dardenne, à: 13/01/14 14:46

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 11 ans 10 mois #13215 par Laurent Dardenne
Correction du code, j'avais laissé la redéfinition de la méthode ToString qui provenait d'un autre contexte d'utilisation.

Todo : ajouter un paramètre $Methods ...

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 11 ans 9 mois #13567 par Laurent Dardenne
Un autre type de construction d'objet basé sur une hashtable résultant d'un traitement, ici une regex déclarant des captures nommées.

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 11 ans 9 mois #13569 par Matthew BETTON
Bonjour Laurent,

Laurent Dardenne écrit:

Un autre type de construction d'objet basé sur une hashtable résultant d'un traitement, ici une regex déclarant des captures nommées.


Juste une petite remarque au sujet de cet article très intéressant.

On parle ici de dynamisme, mais pourtant, dans l'exemple donné, on ne peut pas formater la pattern avec n'importe quel nom à n'importe quelle place.

A un nom est associé une regex particulière.

On doit donc connaitre à l'avance $Names ... ce qui est déjà moins dynamique.

@+

Matthew

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 11 ans 9 mois #13571 par Laurent Dardenne
Matthew BETTON écrit:

On doit donc connaitre à l'avance $Names ... ce qui est déjà moins dynamique.

Oui, c'est plus du paramètrage, car dans l'exemple on ne crée pas de code mais juste une hashtable afin de créer un objet.

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 11 ans 3 semaines #15995 par Laurent Dardenne
Matthew BETTON écrit:

On doit donc connaitre à l'avance $Names ... ce qui est déjà moins dynamique.

Ou créer une fonction dédié :
[code:1]
function New-MatchesObject{
#A partir d'une chaîne de caractères,
#construit un objet personnalisé à l'aide d'une regex
#utilisant des captures nommées.

#Exemple :
# #hashtable de paramètrages
# $MyObject=@{
# #hashtable de création d'objets
# SMB=@{
# #Ces entrées portent les mêmes noms
# #que les paramètres de la fonction New-MatchesObject.
# #Ce qui autorise le splatting
#
# #Hashtable de création d'un objet
# #Exemple : analyse d'attribut AD extensionAttributeN
# Res_CN=@{
# #Nom du type affiché par Get-member ou $Variable.PsObject.TypeNames
# TypeName='MY.SMB.Res_CN'
# #Expression régulière contenant des captures nommées
# #celles-ci seront utilisées pour construire des propriètés d'objets PS personnalisés
# Regex='^extensionAttribute(?&lt;Type&gt;1)#CN=(?&lt;CN&gt;.*?),'
# #On supprime dans la variable automatique $Matches les clés indiquées
# Keys=0,1
# }
#
# Res_DN=@{
# TypeName='MY.SMB.Res_DN'
# Regex='^extensionAttribute(?&lt;Type&gt;1)#(?&lt;DistinguishedName&gt;.*$)'
# Keys=0,1
# }
# };
# #Others=@{...}
# }#$MyObject
#
# $S=\&quot;extensionAttribute1#CN=MyCN,...\&quot;
#
# #Le splatting ne fonctionne avec @Myobject.SMB.Res_CN
# $Parameters=$Myobject.SMB.Res_CN
# $o=New-MatchesObject $S @Parameters
# $o|gm
# $O
#
# $S2=\&quot;extensionAttribute1#MyDN\&quot;
# $Parameters=$Myobject.SMB.Res_DN
# $o2=New-MatchesObject $S2 @Parameters
# $o2|gm
# $O2

param (
#Objet sur lequel on exécute la regex
[Parameter(Mandatory=$true,position=0)]
[ValidateNotNullOrEmpty()]
$InputObject,

#Nom du type de l'objet PS
[Parameter(Mandatory=$true,position=1)]
[ValidateNotNullOrEmpty()]
[String] $TypeName,

#Expression régulière appliquée sur le paramètre InputObject
[Parameter(Mandatory=$true,position=2)]
[ValidateNotNullOrEmpty()]
[String] $Regex,

#En cas de succès de la regex,
#on supprime les noms de clé indiquées dans la hashtable $Matches
[Parameter(Mandatory=$false,position=3)]
[ValidateNotNullOrEmpty()]
#la clé 0 contient l'intégralité de ligne analysée
[Object[]] $Keys=0
)
Write-debug \&quot;New-MatchesObject\&quot;
if ($InputObject -match $Regex)
{
$Keys|
Foreach {
Write-Debug \&quot;Remove key = $_\&quot;
$matches.Remove($_)
}
Write-debug \&quot;Construction d'un objet de type : $($TypeName)\&quot;
$Object=New-Object PSCustomObject -Property $Matches
$Object.PsObject.TypeNames.Insert(0,$TypeName)
Write-Output $Object
}
}#New-MatchesObject
[/code:1]
On peut appeler la fonction en précisant le paramètre ou en utilisant le splatting via une hashtable.

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.073 secondes
Propulsé par Kunena