我使用Powershell的custom-object命令来保存数据点。自定义对象只创建一个对象并为其分配变量。 Powershell可以更进一步,创建可以制作对象的新类吗?
在下面的示例中,我存储了三个数据:服务器名称,时间戳以及自服务器上发生事件以来的分钟数。
当我学习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与数组不兼容,所以我开始使用自定义对象:
$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
这是正确的导出,处理对象属性比处理二维数组中的列更容易。
但是如果我想创建几个不在数组中的自定义对象,我必须一遍又一遍地编写自定义对象代码。
$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
如果除自定义对象之外,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
在Powershell中可以吗?
答案 0 :(得分:37)
您可以在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;
答案 1 :(得分:19)
你可以使用函数作为自定义对象的虚构造函数。您不必复制代码,也可以使用标志从函数调用中设置属性。这是一个例子:
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
}
一些示例输出:
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
你可以使用超出此问题范围的功能来完成大量的工作。相反,请查看about_functions_advanced。
答案 2 :(得分:1)
另一种选择。
您可以将属性消息的'$ null'值替换为初始值。 Prop对象是键(属性)和值(初始值)的哈希表。
$messageClass = New-Object -TypeName PSObject -Prop @{ message = $null; }
$messageClass | Add-Member -MemberType ScriptMethod -Name "ShowMessage" -Value {
Try
{
Write-Host $this.message
}
Catch
{
Throw $_.Exception
}
}
下面的代码描述了一个构造函数。多态性是使用[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
}
然后可以像这样调用构造函数:
$var1 = 'Hello'
$var2 = 'World'
$example1 = MessageClass -mandatoryMessage $var1
$example2 = MessageClass -mandatoryMessage $var1 -optionalMessage $var2
显示文字:
$example1.ShowMessage()
$example2.ShowMessage()
结果将是:
您好!
Hello World!
答案 3 :(得分:0)
为了获得最佳性能,我会这样做:
Add-Type -TypeDefinition '
public class recordEntry {
public string server;
public System.DateTime timestamp;
public int minutes;
public recordEntry(string _server, System.DateTime _timestamp, int _minutes) {
server = _server;
timestamp = _timestamp;
minutes = _minutes;
}
}'
$record = [System.Collections.ArrayList]@()
$record = foreach ($j in 0..10){
[recordEntry]::new("Server1", [datetime]::Now, $j)
}
$record | export-csv -path c:\record.csv -NoTypeInformation