Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I serialize a complex Powershell array to disk for processing by a second Script?

I am collecting statistics about an Exchange environment and need to collect statistics about all the DNS domains in use.

This is a long and intensive operation that can take a long time. I want to persist these values to disk, so I can run a post-processor on the summary.

How should I alter the script I wrote below so that I can run the post-processor?

$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
   }
}

If you can tell from the placeholders, I intend to look at the MX records, SSL certs and other aspects of each DNS domain located.

The intent is to gain enough information about the domains in use so that each domain can be prioritized as needed.

The array $dict when sent to the screen looks like this: (domains truncated for privacy)

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}

An individual object looks like this:

[PS] C:\scripts>$dict["sol.com"]

Name                           Value
----                           -----
DNS_SRV
CountSecondary                 3
CountWindows                   0
IsAcceptedDomain               0
DNS_MX
SSL
CountPrimary                   0
like image 245
makerofthings7 Avatar asked Nov 07 '15 15:11

makerofthings7


1 Answers

You can use Export-CliXml to serialize and write the values to disk. Import-CliXml to deserialize it and bring it back in.

You may need to use the -Depth parameter if your objects are nested, I believe it defaults to 2 levels. Increasing the levels can vastly increase the time taken for serialization; especially if you have circular references.

If you want to serialize/deserialize in memory, you can use [System.Management.Automation.PSSerializer]::Serialize() and [System.Management.Automation.PSSerializer]::Deserialize() (these are used internally by the cmdlets, so it's the same representation).

like image 172
briantist Avatar answered Oct 13 '22 13:10

briantist