I use Powershell's custom-object command to hold data points. Custom-object creates just one object and assigns a variable to it. Can Powershell go one step further and create new classes from which objects can be made?
我使用Powershell的custom-object命令来保存数据点。自定义对象只创建一个对象并为其分配变量。 Powershell可以更进一步,创建可以制作对象的新类吗?
In the examples below, I store three pieces of data: a server name, a timestamp, and the minutes since an event occurred on the server.
在下面的示例中,我存储了三个数据:服务器名称,时间戳以及自服务器上发生事件以来的分钟数。
When I was learning Powershell, I put all this into a two-dimensional array:
当我学习Powershell时,我把所有这些都放到了一个二维数组中:
$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 doesn't play well with arrays, so I started using a custom object:
export-csv与数组不兼容,所以我开始使用自定义对象:
$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
That's exports correctly, and dealing with object properties is easier than dealing with columns in a two-dimensional array.
这是正确导出的,处理对象属性比处理二维数组中的列更容易。
But if I want to create several custom objects that aren't in an array, I have to write the custom-object code over and over again.
但是如果我想创建几个不在数组中的自定义对象,我必须一遍又一遍地编写自定义对象代码。
$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
What if Powershell could design custom classes in addition to custom objects? Like OO programming languages do? Something like:
如果Powershell除自定义对象外还可以设计自定义类,该怎么办?像OO编程语言一样吗?就像是:
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
Is that possible in Powershell?
在Powershell中有可能吗?
3 个解决方案
#1
36
You can define classes in PowerShell.
您可以在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;
#2
19
You could use a function as a faux constructor for your custom objects. You wouldn't ever have to duplicate your code, and you could use flags to set your properties right from the function call. Here's an example:
您可以将函数用作自定义对象的虚构造函数。您不必复制代码,也可以使用标志从函数调用中设置属性。这是一个例子:
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
}
And some sample output:
还有一些示例输出:
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
You can do a whole ton of stuff with functions that is out of the scope of this question. Instead, check out about_functions_advanced.
你可以使用超出这个问题范围的功能来完成大量的工作。相反,请查看about_functions_advanced。
#3
1
Another option.
另外一个选择。
Properties
You can replace the '$null' value of the property message to have an initial value. The Prop object is a hashtable of keys (properties) and values (initial values).
您可以替换属性消息的'$ null'值以获得初始值。 Prop对象是键(属性)和值(初始值)的哈希表。
$messageClass = New-Object -TypeName PSObject -Prop @{ message = $null; }
Methods
$messageClass | Add-Member -MemberType ScriptMethod -Name "ShowMessage" -Value {
Try
{
Write-Host $this.message
}
Catch
{
Throw $_.Exception
}
}
Constructors
The code below describes a constructor. Polymorphism is achieved using [Parameter(Mandatory=$false)] to assert or not the provision of the specified parameter.
下面的代码描述了一个构造函数。使用[Parameter(Mandatory = $ false)]来断言多态,以断言或不断言指定参数的提供。
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
}
The constructor can then be called like this:
然后可以像这样调用构造函数:
$var1 = 'Hello'
$var2 = 'World'
$example1 = MessageClass -mandatoryMessage $var1
$example2 = MessageClass -mandatoryMessage $var1 -optionalMessage $var2
To show the text:
要显示文字:
$example1.ShowMessage()
$example2.ShowMessage()
The results would be:
结果将是:
Hello!
你好!
Hello World!
你好,世界!
#1
36
You can define classes in PowerShell.
您可以在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;
#2
19
You could use a function as a faux constructor for your custom objects. You wouldn't ever have to duplicate your code, and you could use flags to set your properties right from the function call. Here's an example:
您可以将函数用作自定义对象的虚构造函数。您不必复制代码,也可以使用标志从函数调用中设置属性。这是一个例子:
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
}
And some sample output:
还有一些示例输出:
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
You can do a whole ton of stuff with functions that is out of the scope of this question. Instead, check out about_functions_advanced.
你可以使用超出这个问题范围的功能来完成大量的工作。相反,请查看about_functions_advanced。
#3
1
Another option.
另外一个选择。
Properties
You can replace the '$null' value of the property message to have an initial value. The Prop object is a hashtable of keys (properties) and values (initial values).
您可以替换属性消息的'$ null'值以获得初始值。 Prop对象是键(属性)和值(初始值)的哈希表。
$messageClass = New-Object -TypeName PSObject -Prop @{ message = $null; }
Methods
$messageClass | Add-Member -MemberType ScriptMethod -Name "ShowMessage" -Value {
Try
{
Write-Host $this.message
}
Catch
{
Throw $_.Exception
}
}
Constructors
The code below describes a constructor. Polymorphism is achieved using [Parameter(Mandatory=$false)] to assert or not the provision of the specified parameter.
下面的代码描述了一个构造函数。使用[Parameter(Mandatory = $ false)]来断言多态,以断言或不断言指定参数的提供。
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
}
The constructor can then be called like this:
然后可以像这样调用构造函数:
$var1 = 'Hello'
$var2 = 'World'
$example1 = MessageClass -mandatoryMessage $var1
$example2 = MessageClass -mandatoryMessage $var1 -optionalMessage $var2
To show the text:
要显示文字:
$example1.ShowMessage()
$example2.ShowMessage()
The results would be:
结果将是:
Hello!
你好!
Hello World!
你好,世界!