如何将复杂的 Powershell 数组序列化到磁盘以供第二个脚本处理?
How can I serialize a complex Powershell array to disk for processing by a second Script?
我正在收集有关 Exchange 环境的统计信息,并且需要收集有关所有正在使用的 DNS 域的统计信息。
这是一项漫长而密集的操作,可能需要很长时间。我想将这些值保存到磁盘,因此我可以 运行 摘要上的 post 处理器。
我应该如何更改我在下面编写的脚本,以便我可以 运行 post-处理器?
$dict = @{}
$AcceptedDomains = Get-AcceptedDomain | select domainname
foreach($ad in $AcceptedDomains)
{
$tmp = $dict[$ad.DomainName]
if ($tmp -eq $null)
{
$obj1 = @{CountPrimary = 0; CountWindows =0; CountSecondary = 0; IsAcceptedDomain = 0; DNS_MX = ""; DNS_SRV= ""; SSL=""}
$dict.Add($ad.DomainName.ToString(), $obj1)
}
$dict[$ad.DomainName.ToString()].IsAcceptedDomain = 1
}
foreach($currentmb in get-mailbox -resultsize unlimited|select PrimarySMTPAddress, WindowsEmailAddress, EmailAddresses)
{
$domName = $currentmb.PrimarySmtpAddress.ToString().Split("@")[1].ToString();
$tmp = $dict[ $domName]
if ($tmp -eq $null)
{
$obj1 = @{CountPrimary = 0; CountWindows =0; CountSecondary = 0; IsAcceptedDomain = 0; DNS_MX = ""; DNS_SRV= ""; SSL=""}
$dict.Add( $domName, $obj1)
}
$dict[$domName].CountPrimary+= 1
$domName = $currentmb.WindowsEmailAddress.ToString().Split("@")[1].ToString();
$tmp = $dict[ $domName]
if ($tmp -eq $null)
{
$obj1 = @{CountPrimary = 0; CountWindows =0; CountSecondary = 0; IsAcceptedDomain = 0; DNS_MX = ""; DNS_SRV= ""; SSL=""}
$dict.Add( $domName, $obj1)
}
$dict[$domName].CountWindows += 1
$secondaries = New-Object System.Collections.ArrayList($null)
$currentMBSmtp = $currentMB.EmailAddresses | where {$_.PrefixString -eq "SMTP"} | select SMTPAddress
foreach($smtp1 in $currentMBSmtp)
{
$smtp1Domain = $smtp1.SmtpAddress.ToString().Split("@")[1].ToString()
$secondaries.Add($smtp1Domain)
}
foreach($domName1 in $secondaries | select -unique)
{
$tmp = $dict[ $domName1]
if ($tmp -eq $null)
{
$obj1 = @{CountPrimary = 0; CountWindows =0; CountSecondary = 0; IsAcceptedDomain = 0; DNS_MX = ""; DNS_SRV= ""; SSL=""}
$dict.Add( $domName1, $obj1)
}
$dict[$domName1].CountSecondary += 1
}
}
如果你能从占位符中看出,我打算查看每个 DNS 域所在的 MX 记录、SSL 证书和其他方面。
目的是获得有关正在使用的域的足够信息,以便可以根据需要确定每个域的优先级。
数组 $dict
发送到屏幕时如下所示:(域 t运行 出于隐私考虑)
oup.com {DNS_SRV, CountSecondary, CountWindows, IsAcceptedDomain, DNS_MX, SSL, CountPrimary}
isorygroup... {DNS_SRV, CountSecondary, CountWindows, IsAcceptedDomain, DNS_MX, SSL, CountPrimary}
ces.com {DNS_SRV, CountSecondary, CountWindows, IsAcceptedDomain, DNS_MX, SSL, CountPrimary}
nc.net {DNS_SRV, CountSecondary, CountWindows, IsAcceptedDomain, DNS_MX, SSL, CountPrimary}
单个对象如下所示:
[PS] C:\scripts>$dict["sol.com"]
Name Value
---- -----
DNS_SRV
CountSecondary 3
CountWindows 0
IsAcceptedDomain 0
DNS_MX
SSL
CountPrimary 0
您可以使用 Export-CliXml
序列化并将值写入磁盘。 Import-CliXml
将其反序列化并将其带回。
如果您的对象是嵌套的,您可能需要使用 -Depth
参数,我相信它默认为 2 层。增加级别会大大增加序列化所需的时间;特别是如果你有循环引用。
如果你想 serialize/deserialize 在内存中,你可以使用 [System.Management.Automation.PSSerializer]::Serialize()
和 [System.Management.Automation.PSSerializer]::Deserialize()
(这些由 cmdlet 内部使用,所以它是相同的表示)。
我正在收集有关 Exchange 环境的统计信息,并且需要收集有关所有正在使用的 DNS 域的统计信息。
这是一项漫长而密集的操作,可能需要很长时间。我想将这些值保存到磁盘,因此我可以 运行 摘要上的 post 处理器。
我应该如何更改我在下面编写的脚本,以便我可以 运行 post-处理器?
$dict = @{}
$AcceptedDomains = Get-AcceptedDomain | select domainname
foreach($ad in $AcceptedDomains)
{
$tmp = $dict[$ad.DomainName]
if ($tmp -eq $null)
{
$obj1 = @{CountPrimary = 0; CountWindows =0; CountSecondary = 0; IsAcceptedDomain = 0; DNS_MX = ""; DNS_SRV= ""; SSL=""}
$dict.Add($ad.DomainName.ToString(), $obj1)
}
$dict[$ad.DomainName.ToString()].IsAcceptedDomain = 1
}
foreach($currentmb in get-mailbox -resultsize unlimited|select PrimarySMTPAddress, WindowsEmailAddress, EmailAddresses)
{
$domName = $currentmb.PrimarySmtpAddress.ToString().Split("@")[1].ToString();
$tmp = $dict[ $domName]
if ($tmp -eq $null)
{
$obj1 = @{CountPrimary = 0; CountWindows =0; CountSecondary = 0; IsAcceptedDomain = 0; DNS_MX = ""; DNS_SRV= ""; SSL=""}
$dict.Add( $domName, $obj1)
}
$dict[$domName].CountPrimary+= 1
$domName = $currentmb.WindowsEmailAddress.ToString().Split("@")[1].ToString();
$tmp = $dict[ $domName]
if ($tmp -eq $null)
{
$obj1 = @{CountPrimary = 0; CountWindows =0; CountSecondary = 0; IsAcceptedDomain = 0; DNS_MX = ""; DNS_SRV= ""; SSL=""}
$dict.Add( $domName, $obj1)
}
$dict[$domName].CountWindows += 1
$secondaries = New-Object System.Collections.ArrayList($null)
$currentMBSmtp = $currentMB.EmailAddresses | where {$_.PrefixString -eq "SMTP"} | select SMTPAddress
foreach($smtp1 in $currentMBSmtp)
{
$smtp1Domain = $smtp1.SmtpAddress.ToString().Split("@")[1].ToString()
$secondaries.Add($smtp1Domain)
}
foreach($domName1 in $secondaries | select -unique)
{
$tmp = $dict[ $domName1]
if ($tmp -eq $null)
{
$obj1 = @{CountPrimary = 0; CountWindows =0; CountSecondary = 0; IsAcceptedDomain = 0; DNS_MX = ""; DNS_SRV= ""; SSL=""}
$dict.Add( $domName1, $obj1)
}
$dict[$domName1].CountSecondary += 1
}
}
如果你能从占位符中看出,我打算查看每个 DNS 域所在的 MX 记录、SSL 证书和其他方面。
目的是获得有关正在使用的域的足够信息,以便可以根据需要确定每个域的优先级。
数组 $dict
发送到屏幕时如下所示:(域 t运行 出于隐私考虑)
oup.com {DNS_SRV, CountSecondary, CountWindows, IsAcceptedDomain, DNS_MX, SSL, CountPrimary}
isorygroup... {DNS_SRV, CountSecondary, CountWindows, IsAcceptedDomain, DNS_MX, SSL, CountPrimary}
ces.com {DNS_SRV, CountSecondary, CountWindows, IsAcceptedDomain, DNS_MX, SSL, CountPrimary}
nc.net {DNS_SRV, CountSecondary, CountWindows, IsAcceptedDomain, DNS_MX, SSL, CountPrimary}
单个对象如下所示:
[PS] C:\scripts>$dict["sol.com"]
Name Value
---- -----
DNS_SRV
CountSecondary 3
CountWindows 0
IsAcceptedDomain 0
DNS_MX
SSL
CountPrimary 0
您可以使用 Export-CliXml
序列化并将值写入磁盘。 Import-CliXml
将其反序列化并将其带回。
如果您的对象是嵌套的,您可能需要使用 -Depth
参数,我相信它默认为 2 层。增加级别会大大增加序列化所需的时间;特别是如果你有循环引用。
如果你想 serialize/deserialize 在内存中,你可以使用 [System.Management.Automation.PSSerializer]::Serialize()
和 [System.Management.Automation.PSSerializer]::Deserialize()
(这些由 cmdlet 内部使用,所以它是相同的表示)。