J'utilise la commande d'objet personnalisé de Powershell pour contenir des points de données. Custom-object crée un seul objet et lui assigne une variable. Powershell peut-il aller plus loin et créer de nouvelles classes à partir desquelles des objets peuvent être créés?
Dans les exemples ci-dessous, je stocke trois données: un nom de serveur, un horodatage et les minutes depuis qu'un événement s'est produit sur le serveur.
Quand j'apprenais Powershell, j'ai mis tout cela dans un tableau à deux dimensions:
$record = @("Server","Timestamp","Minutes")
for ($j = 0; $j -lt 10; $j++){
$record += @("Server1","$(get-date)",$j)
sleep 60
}
$record | export-csv -path c:\record.csv -no type information
export-csv ne fonctionne pas bien avec les tableaux, j'ai donc commencé à utiliser un objet personnalisé:
$record = @()
for ($j = 0; $j -lt 10; $j++){
$r = New-Object -TypeName PSObject
$r | Add-Member -MemberType NoteProperty -Name Server -Value ""
$r | Add-Member -MemberType NoteProperty -Name Timesteamp -Value ""
$r | Add-Member -MemberType NoteProperty -Name Minutes -Value ""
$r.server = "Server1"
$r.timestamp = "$(get-date)"
$r.minutes = "$j"
$record += $r
sleep 60
}
$record | export-csv -path c:\record.csv -no type information
Cela s'exporte correctement et il est plus facile de traiter les propriétés des objets que de traiter les colonnes d'un tableau à deux dimensions.
Mais si je veux créer plusieurs objets personnalisés qui ne sont pas dans un tableau, je dois écrire le code d'objet personnalisé encore et encore.
$server1 = New-Object -TypeName PSObject
$server1 | Add-Member -MemberType NoteProperty -Name Server -Value ""
$server1 | Add-Member -MemberType NoteProperty -Name Timesteamp -Value ""
$server2 = New-Object -TypeName PSObject
$server2 | Add-Member -MemberType NoteProperty -Name Server -Value ""
$server2 | Add-Member -MemberType NoteProperty -Name Timesteamp -Value ""
#ad nauseum
Et si Powershell pouvait concevoir des classes personnalisés en plus des objets personnalisés? Comme OO les langages de programmation font? Quelque chose comme:
class record {
-MemberType NoteProperty -Name Server -Value ""
-MemberType NoteProperty -Name Timestamp -Value ""
-MemberType NoteProperty -Name Minutes -Value ""
}
$server1 = new-object -TypeName record
$server2 = new-object -TypeName record
$server3 = new-object -TypeName record
Est-ce possible à Powershell?
Vous pouvez définir des classes dans PowerShell.
Add-Type -Language CSharp @"
public class Record{
public System.DateTime TimeStamp;
public string Server;
public int Minutes;
}
"@;
$MyRecord = new-object Record;
$MyRecord.Server = "myserver";
$MyRecord.Timestamp = Get-Date;
$MyRecord.Minutes = 15;
Vous pourriez utiliser une fonction comme un faux constructeur pour vos objets personnalisés. Vous n'auriez jamais à dupliquer votre code et vous pourriez utiliser des indicateurs pour définir vos propriétés directement à partir de l'appel de fonction. Voici un exemple:
Function New-Constructor
{
param
(
[string]$Name,
[DateTime]$TimeStamp = (Get-Date)
)
$server = New-Object -TypeName PSObject
$server | Add-Member -MemberType NoteProperty -Name Server -Value $Name
$server | Add-Member -MemberType NoteProperty -Name TimeStamp -Value $TimeStamp
# Calling "server" below outputs it, acting as a "return" value
$server
}
Et quelques exemples de sortie:
PS C:\> New-Constructor -Name "MyServer"
Server TimeStamp
------ ---------
MyServer 9/9/2013 3:27:47 PM
PS C:\> $myServer = New-Constructor -Name "MyServer"
PS C:\> $myServer
Server TimeStamp
------ ---------
MyServer 9/9/2013 3:27:57 PM
PS C:\> $newServer = New-Constructor -Name "NS" -TimeStamp (Get-Date).AddDays(-1)
PS C:\> $newServer
Server TimeStamp
------ ---------
NS 9/8/2013 3:33:00 PM
Vous pouvez faire une tonne de choses avec des fonctions qui sortent du cadre de cette question. Au lieu de cela, consultez about_functions_advanced .
Une autre option.
Vous pouvez remplacer la valeur '$ null' du message de propriété pour avoir une valeur initiale. L'objet Prop est une table de hachage des clés (propriétés) et des valeurs (valeurs initiales).
$messageClass = New-Object -TypeName PSObject -Prop @{ message = $null; }
$messageClass | Add-Member -MemberType ScriptMethod -Name "ShowMessage" -Value {
Try
{
Write-Host $this.message
}
Catch
{
Throw $_.Exception
}
}
Le code ci-dessous décrit un constructeur. Le polymorphisme est obtenu à l'aide de [Parameter (Mandatory = $ false)] pour affirmer ou non la fourniture du paramètre spécifié.
function MessageClass {
param([Parameter(Mandatory=$true)]
[String]$mandatoryMessage,
[Parameter(Mandatory=$false)]
[String]$optionalMessage)
$messageObj = $messageClass.psobject.copy()
if ($optionalMessage)
{
$messageObj.message = "$mandatoryMessage $optionalMessage!"
}
else
{
$messageObj.message = "$mandatoryMessage!"
}
$messageObj
}
Le constructeur peut alors être appelé comme ceci:
$var1 = 'Hello'
$var2 = 'World'
$example1 = MessageClass -mandatoryMessage $var1
$example2 = MessageClass -mandatoryMessage $var1 -optionalMessage $var2
Pour afficher le texte:
$example1.ShowMessage()
$example2.ShowMessage()
Les résultats seraient:
Salut!
Bonjour le monde!