Question Re:[fonction] New-PSCustomObjectFunction (Dynamisme)
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
Réduire
Plus d'informations
- Messages : 6302
- Remerciements reçus 68
il y a 7 ans 7 mois - il y a 3 ans 7 mois #23250
par Laurent Dardenne
Tutoriels PowerShell
Réponse de Laurent Dardenne sur le sujet Re:[fonction] New-PSCustomObjectFunction (Dynamisme)
Nouvelle version de New-MatchesObject, elle gère mnt les captures optionnelles :Pour le dernier exemple tous les objets personnalisés ont la même structure, les captures optionnelles sont remplacées par des propriété aynt une valeur $null.
function New-MatchesObject{
#v2
#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(?<Type>1)#CN=(?<CN>.*?),'
# #On supprime dans la variable automatique $Matches les clés indiquées
# Keys=0,1
# }
#
# Res_DN=@{
# TypeName='MY.SMB.Res_DN'
# Regex='^extensionAttribute(?<Type>1)#(?<DistinguishedName>.*$)'
# Keys=0,1
# }
# };
# #Others=@{...}
#
# }#$MyObject
#
# $S="extensionAttribute1#CN=MyCN,..."
#
# #Le splatting ne fonctionne avec @Myobject.SMB.Res_CN
# $Parameters=$Myobject.SMB.Res_CN
# $o=New-MatchesObject $S @Parameters
# $o|gm
# $O
#
# $S2="extensionAttribute1#MyDN"
# $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
#celles-ci sont des groupes de capture
[Parameter(Mandatory=$false,position=3)]
[ValidateNotNullOrEmpty()]
#la clé 0 contient l'intégralité de ligne analysée
[Object[]] $Keys=0
)
Function Select-NamedCapture {
#Extrait les noms de capture présent dans la regex
Param( [string] $RegexStr )
$Pattern='\?\<(.*?)\>'
$Regex = new-object regex $Pattern
$CurrentMatch = $Regex.match($RegexStr)
if (!$CurrentMatch.Success)
{ Write-debug "Echec :$RegexStr" }
else
{ $CurrentMatch.Groups[1].Value }
while ($CurrentMatch.Success)
{
$CurrentMatch = $CurrentMatch.NextMatch()
if ($CurrentMatch.Success)
{ $CurrentMatch.Groups[1].Value }
}
}#Select-NamedCapture
Write-debug "New-MatchesObject"
$NamesOfCaptures=Select-NamedCapture -RegexStr $Regex
if ($InputObject -match $Regex)
{
#Conflit possible entre un nom de capture numérique ('1') et le numéro d'un groupe : 1
#dans ce cas on 'perd la capture :
# #$Str="^(?<11>toto) (titi)"
# $Str="^(?'1'toto) (titi)"
# 'toto titi' -match $str
Write-Debug "$($matches.GetEnumerator()|% {"{0}={1}" -f $_.key,$_.Value})"
$Keys|
Foreach {
Write-Debug "Remove key : $_"
#Pour les captures optionnelles,
#si la clé n'existe pas il n'y a pas d'erreur
$matches.Remove($_)
}
#Si des captures sont optionnelles, exemple "^(?<Vide>(ab){0,1})",
# on compléte les propriétés manquantes. todo redondant ? $Matches contient la capture 'vide'
Compare-Object ([string[]]$Matches.Keys) $NamesOfCaptures|
Select -ExpandProperty InputObject|
Foreach-Object {
Write-Debug "Add optionnal key : $_"
$Matches.Add($_,$Null)
}
Write-debug "Construction d'un objet de type : $($TypeName)"
$Object=New-Object PSCustomObject -Property $Matches
$Object.PsObject.TypeNames.Insert(0,$TypeName)
Write-Output $Object
} #sinon on ne renvoi pas d'objet ayant toutes ses propriété à $null
} #New-MatchesObject
$InfArchitecture=@{
TypeName='INF.Architecture'
Regex='^(?<ManufacturerName>.*?),nt(?<Architecture>.*?)\.(?<OSMajorVersion>.*?)\.(?<OSMinorVersion>.*?)((\.(?<ProductType>.*?))?(\.(?<SuiteMask>.*?))?)$'
Keys=0,1,2,3,4
}
$Manufacturer='AMD,NTx86.6.2'
$O=New-MatchesObject $Manufacturer @InfArchitecture
$O
$O|gm
$Manufacturer=@(
'AMD,NTx86.6.2'
'AMD,NTx86.6.2.5'
'AMD,NTx86.6.2.5.9'
'AMD,NTx86.6.2.0x0000001'
'AMD,NTx86.6.2.0x0000001.0x00000002'
'AMD,NTx86.6.2.0x00000002'
)
$Manufacturer |Foreach-Object { New-MatchesObject $_ @INfArchitecture}
Tutoriels PowerShell
Dernière édition: il y a 3 ans 7 mois par Laurent Dardenne. Raison: formatage
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
Réduire
Plus d'informations
- Messages : 6302
- Remerciements reçus 68
il y a 3 ans 5 mois - il y a 3 ans 5 mois #30829
par Laurent Dardenne
Tutoriels PowerShell
Réponse de Laurent Dardenne sur le sujet Re:[fonction] New-PSCustomObjectFunction (Dynamisme)
Autre construction possible basée sur des variables déclarée via 'PipelineVariable' :
L''exemple suivant recherche dans des fichiers de log d'une application, les sessions qui ne sont à priori pas close :
Les variables contextuelles 'Line' et 'CurrentFile' sont recopiées dans un objet personnalisé émis dans le pipeline.
function New-SimplePSObject{
Param(
[string[]] $Property
)
$O=[PSCustomObject]::New()
#Suppose qu'il existe dans l'appelant une variable du nom de la propriété
#Sinon la propriété contiendra $null
$Property|
ForEach-Object {
$Value=(Get-Variable $_ -ErrorAction SilentlyContinue).Value
Add-Member -InputObject $O -MemberType NoteProperty -Name $_ -Value $Value
}
$O
}
L''exemple suivant recherche dans des fichiers de log d'une application, les sessions qui ne sont à priori pas close :
# Date à 0h:0m:0s
$Now=[datetime]::now.Date
$List=Get-ChildItem c:\projet\Logs\*.log|
Where-Object { $_.LastAccessTime.Date -eq $Now }
$FileInfo=foreach ($CurrentFile in $List){
Get-Content $CurrentFile|
Select-Object -Last 1 -PipelineVariable Line|
Select-String -Pattern "Close with exit code '0'" -NotMatch -Quiet|
Foreach-Object {
New-SimplePSObject Line,CurrentFile,NotExist
}
}
$FileInfo|Format-List
Les variables contextuelles 'Line' et 'CurrentFile' sont recopiées dans un objet personnalisé émis dans le pipeline.
Tutoriels PowerShell
Dernière édition: il y a 3 ans 5 mois par Laurent Dardenne.
Connexion ou Créer un compte pour participer à la conversation.
Temps de génération de la page : 0.099 secondes
- Vous êtes ici :
- Accueil
- forum
- PowerShell
- Contributions à la communauté
- Re:[fonction] New-PSCustomObjectFunction (Dynamisme)