ItmWebService.psm1

#
# Level3 ITM Web Service Control
# John Cravener
# 2014-10-19
# v1.5
# 2015-06-23
# v1.6
# 2016-10-14
# v1.6

function New-ItmAuthenticatedWebServiceProxy
{
    <#
        .Synopsis
        Creates an authenticated web service proxy to the Level3 ITM SOAP web service.
 
        .Description
        Creates an authenticated web service proxy to the Level3 ITM SOAP web service. The cmdlet
        prompts the user for a user name and password and returns a web-service proxy object that
        has been authenticated against the ITM service. This object is required by all the other
        cmdlets in this module.
 
        .Parameter URI
        The URI of the ITM SOAP web service.
  
 
        .Example
        New-ItmAuthenticatedWebServiceProxy
 
        VERBOSE: Making connection to https://admin.nsatc.net/ITM.wsdl
 
        cmdlet Get-ItmAuthToken at command pipeline position 1
        Supply values for the following parameters:
        UserName: Domain/user
        Password: **********
 
        ItmWebSeviceProxy
        -----------------
        Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy1tps___admin_nsatc_net_ITM_wsdl.ITMService
    #>


    param(
            [parameter(Mandatory=$false)]
            [String]$URI = 'https://admin.nsatc.net/ITM.wsdl'
         )

    begin
    {
        $itmws = $null
        $tokenitm = $null
        $ObjectType = 'ItmAuthenticatedWebServiceProxy'
        $o = @()
    }

    process
    {
        try
        {
            $itmws = Connect-ItmWebService -URI $URI -Verbose
        }
        catch [System.Exception]
        {
            $Error[0]
            return
        }

        try
        {
            $tokenitm = Get-ItmAuthToken -ItmWebSeviceProxy $itmws
        }
        catch [System.Exception]
        {
            $Error[0]
            return
        }
        
        $o = New-Object -TypeName psobject -Property @{'ItmWebSeviceProxy' = $itmws; 'ItmAuthToken' = $tokenitm }

        if($Host.Version.Major -ge 3)
        {
            $o.pstypenames.add($ObjectType)

            if((Get-TypeData -TypeName $ObjectType) -eq $null)
            {
                Update-TypeData -TypeName $ObjectType -DefaultDisplayPropertySet ItmWebSeviceProxy
            }
        }

        if( -not $o.ItmWebSeviceProxy)
        {
            Write-Error -Message "Login did not complete correctly."
        }
        else
        {
            $o
        }
    }

    end{}
}


function Connect-ItmWebService
{
    <#
        .Synopsis
        Makes an unauthenticated connection to the Level3 ITM SOAP web service.
 
        .Description
        Makes an unauthenticated connection to the Level3 ITM SOAP web service. It simply returns
        a conneceted web service proxy object to the service endpoint.
 
        This is a low level cmdlet for use in writing scripts. It is typically not needed for
        interactive use of the ItmWebService module. The best way to make use of the cmdlets
        in this module is to first run the New-ItmAuthenticatedWebServiceProxy cmdlet which will
        setup an authenticated connection to the service endpoint.
 
        .Parameter URI
        The URI of the ITM SOAP web service.
  
 
        .Example
        Connect-ItmWebService
 
        SoapVersion : Default
        AllowAutoRedirect : False
        CookieContainer :
        ClientCertificates : {}
        EnableDecompression : False
        UserAgent : Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 4.0.30319.34014)
        Proxy :
        UnsafeAuthenticatedConnectionSharing : False
        Credentials :
        UseDefaultCredentials : False
        ConnectionGroupName :
        PreAuthenticate : False
        Url : https://admin.nsatc.net/cgi-bin/soap.pl
        RequestEncoding :
        Timeout : 100000
        Site :
        Container :
    #>


    param(
        
            [parameter(Mandatory=$false)]
            [String]$URI = 'https://admin.nsatc.net/ITM.wsdl'
         )
    
    begin{}
    process{Write-Verbose -Message "Making connection to $URI"; New-WebServiceProxy -Uri $URI}
    end{}
}

function Get-ItmAuthToken
{
    <#
        .Synopsis
        Requests an authentication token to the Level3 ITM SOAP web service.
 
        .Description
        Requests and returns an authentication token to the Level3 ITM SOAP web service.
        A token will be return if a valid set of ITM credentials are passed to this cmdlet.
 
        The cmdlet optionally allows for the username to be passed on the command line. The
        pasword may only be passed by typing it in from the interactive prompt.
 
        This is a low level cmdlet for use in writing scripts. It is typically not needed for
        interactive use of the ItmWebService module. The best way to make use of the cmdlets
        in this module is to first run the New-ItmAuthenticatedWebServiceProxy cmdlet which will
        set up an authenticated connection to the service endpoint.
 
        .Parameter ItmWebSeviceProxy
        A connected web service proxy object to the Level3 ITM SOAP web service.
  
        .Parameter UserName
        User name portion of the ITM credentials.
   
        .Example
        Get-ItmAuthToken -ItmWebSeviceProxy $var -UserName Domain/user
        Password: **********
        3e070ae457943db80eb85a7d3040119c
    #>


    param(
            [parameter(Mandatory=$true)]
            [ValidateNotNullOrEmpty()]
            [System.Object]$ItmWebSeviceProxy = $null,

            [ValidateNotNullOrEmpty()]
            [parameter(Mandatory=$true)]
            [string]$UserName = $null #,

            #[ValidateNotNullOrEmpty()]
            #[parameter(Mandatory=$true)]
            #[String]$PassWord = $null
         )

    begin
    {
        $SecurePassword =  Read-Host -Prompt "Password" -AsSecureString

        $PassWord = ConvertFrom-SecureToPlain -SecurePassword $SecurePassword
    }
    
    process
    {
        $ItmWebSeviceProxy.Login($UserName, $PassWord)
    }
    
    end{}
}

function Close-ItmAuthenticatedWebServiceProxy
{
    param(
            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [System.Object]$ItmWebSeviceProxy = $null,

            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [String]$ItmAuthToken = $null

         )

    begin{}

    process
    {
        try
        {
            $null = $ItmWebSeviceProxy.Logout($ItmAuthToken)

            Write-Verbose -Message "Closing proxy connection..."
        }
        catch [System.Exception]
        {
            $_
            return
        }
    }

    end{}
}

function Get-ItmDomainNameOrigins
{
    param(
            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [System.Object]$ItmWebSeviceProxy = $null,

            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [String]$ItmAuthToken = $null

         )
    
    begin
    {
        $ObjectType = 'DomainNameOrigin'
        $o = @()
        $p = 'DomainNameOrigin'
    }
    
    process
    {
        $o = $ItmWebSeviceProxy.ListDomainNameOrigins($ItmAuthToken) | 

            ForEach-Object { New-Object -TypeName psobject -Property @{'DomainNameOrigin' = $_; 'ItmWebSeviceProxy' =  $ItmWebSeviceProxy; 'ItmAuthToken' = $ItmAuthToken} }

        if($Host.Version.Major -ge 3)
        {
            foreach($oo in $o)
            {
                $oo.pstypenames.add($ObjectType)

                if((Get-TypeData -TypeName $ObjectType) -eq $null)
                {
                    Update-TypeData -TypeName $ObjectType -DefaultDisplayPropertySet $p
                }
            }
        }

        $o
    }
    end{}
}

function Set-ItmCurrentDomainNameOrigin
{
    param(
            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [System.Object]$ItmWebSeviceProxy = $null,

            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [String]$ItmAuthToken = $null,

            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [String]$DomainNameOrigin = $null
         )
    
    begin
    {
        $ObjectType = 'CurrentDomainNameOrigin'
        $o = @()
        $p = 'DomainNameOrigin', 'Current'
    }
    
    process
    {
        $o = $ItmWebSeviceProxy.SetCurrentDomainNameOrigin($ItmAuthToken, $DomainNameOrigin) | 

            ForEach-Object { New-Object -TypeName psobject -Property @{'DomainNameOrigin' = $_; 'Current' = $true; 'ItmWebSeviceProxy' =  $ItmWebSeviceProxy; 'ItmAuthToken' = $ItmAuthToken } }

        if($Host.Version.Major -ge 3)
        {
            foreach($oo in $o)
            {
                $oo.pstypenames.add($ObjectType)

                if((Get-TypeData -TypeName $ObjectType) -eq $null)
                {
                    Update-TypeData -TypeName $ObjectType -DefaultDisplayPropertySet $p
                }
            }
        }

        $o
    }
    end{}
}

function Get-ItmCurrentDomainNameOrigin
{
    param(
            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [System.Object]$ItmWebSeviceProxy = $null,

            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [String]$ItmAuthToken = $null
         )
    
    begin
    {
        $ObjectType = 'CurrentDomainNameOrigin'
        $o = @()
        $p = 'DomainNameOrigin', 'Current'
    }
    process
    {
        $o = $ItmWebSeviceProxy.GetCurrentDomainNameOrigin($ItmAuthToken) | 

            ForEach-Object { New-Object -TypeName psobject -Property @{'DomainNameOrigin' = $_; 'Current' = $true; 'ItmWebSeviceProxy' =  $ItmWebSeviceProxy; 'ItmAuthToken' = $ItmAuthToken} }

        if($Host.Version.Major -ge 3)
        {
            foreach($oo in $o)
            {
                $oo.pstypenames.add($ObjectType)

                if((Get-TypeData -TypeName $ObjectType) -eq $null)
                {
                    Update-TypeData -TypeName $ObjectType -DefaultDisplayPropertySet $p
                }
            }
        }

        $o
    }
    end{}
}

function Get-ItmActivePolicy
{
    param(
            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [System.Object]$ItmWebSeviceProxy = $null,

            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [String]$ItmAuthToken = $null
         )
    
    begin
    {
        $ObjectType = 'ActivePolicy'
        $o = @()
        $p = 'DomainNameOrigin', 'PolicyName', 'Version', 'ActivationTime'
    }

    process
    {
        $dmo = Get-ItmCurrentDomainNameOrigin -ItmWebSeviceProxy $ItmWebSeviceProxy -ItmAuthToken $ItmAuthToken
        
        
        $o = $ItmWebSeviceProxy.ListActivePolicy($ItmAuthToken) | 

            ForEach-Object { New-Object -TypeName psobject -Property @{'DomainNameOrigin' = $dmo.DomainNameOrigin; 'PolicyName' = $_.name; 'Version' = $_.version; 'ActivationTime' = ([DateTime]$_.activated); 'ItmWebSeviceProxy' =  $ItmWebSeviceProxy; 'ItmAuthToken' = $ItmAuthToken} }

        if($Host.Version.Major -ge 3)
        {
            foreach($oo in $o)
            {
                $oo.pstypenames.add($ObjectType)

                if((Get-TypeData -TypeName $ObjectType) -eq $null)
                {
                    Update-TypeData -TypeName $ObjectType -DefaultDisplayPropertySet $p
                }
            }
        }

        $o
    }
    end{}
}

function Get-ItmStoredPolicies
{
    param(
            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [System.Object]$ItmWebSeviceProxy = $null,

            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [String]$ItmAuthToken = $null
         )
    
    begin
    {
        $ObjectType = 'StoredPolicy'
        $o = @()
        $p = 'DomainNameOrigin', 'PolicyName', 'Version', 'LastModifiedTime'
    }

    process
    {
        $dmo = Get-ItmCurrentDomainNameOrigin -ItmWebSeviceProxy $ItmWebSeviceProxy -ItmAuthToken $ItmAuthToken
        
        
        $o = $ItmWebSeviceProxy.ListStoredPolicies($ItmAuthToken) | 

            ForEach-Object { New-Object -TypeName psobject -Property @{'DomainNameOrigin' = $dmo.DomainNameOrigin; 'PolicyName' = $_.name; 'Version' = $_.version; 'LastModifiedTime' = ([DateTime]$_.lastModified); 'ItmWebSeviceProxy' =  $ItmWebSeviceProxy; 'ItmAuthToken' = $ItmAuthToken} }
    
        if($Host.Version.Major -ge 3)
        {
            foreach($oo in $o)
            {
                $oo.pstypenames.add($ObjectType)

                if((Get-TypeData -TypeName $ObjectType) -eq $null)
                {
                    Update-TypeData -TypeName $ObjectType -DefaultDisplayPropertySet $p
                }
            }
        }

        $o
    }
    end{}
}

function Get-ItmPreviouslyActivePolicies
{
    param(
            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [System.Object]$ItmWebSeviceProxy = $null,

            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [String]$ItmAuthToken = $null
         )
    
    begin
    {
        $ObjectType = 'PreviouslyActivePolicies'
        $o = @()
        $p = 'DomainNameOrigin', 'PolicyName', 'Version', 'ActivationOrder', 'DeactivationTime'
    }

    process
    {
        $dmo = Get-ItmCurrentDomainNameOrigin -ItmWebSeviceProxy $ItmWebSeviceProxy -ItmAuthToken $ItmAuthToken
        
        
        $o = $ItmWebSeviceProxy.ListPreviouslyActivePolicies($ItmAuthToken) | 

            ForEach-Object { New-Object -TypeName psobject -Property @{'DomainNameOrigin' = $dmo.DomainNameOrigin; 'PolicyName' = $_.name; 'Version' = $_.version; 'ActivationOrder' = ([int]$_.activationOrder); 'DeactivationTime' = ([DateTime]$_.deactivated); 'ItmWebSeviceProxy' =  $ItmWebSeviceProxy; 'ItmAuthToken' = $ItmAuthToken} }

        if($Host.Version.Major -ge 3)
        {
            foreach($oo in $o)
            {
                $oo.pstypenames.add($ObjectType)

                if((Get-TypeData -TypeName $ObjectType) -eq $null)
                {
                    Update-TypeData -TypeName $ObjectType -DefaultDisplayPropertySet $p
                }
            }
        }

        $o
    }
    end{}
}

function Invoke-ItmActivePolicyDownload
{
    param(
            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [System.Object]$ItmWebSeviceProxy = $null,

            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [String]$ItmAuthToken = $null
         )
    
    begin
    {
        $p = 'DomainNameOrigin', 'PolicyName', 'Version', 'ActivationTime', 'PolicyXml'
    }
    process
    {
        $ap = Get-ItmActivePolicy -ItmWebSeviceProxy $ItmWebSeviceProxy -ItmAuthToken $ItmAuthToken

        [xml]$x = $ItmWebSeviceProxy.DownloadActivePolicy($ItmAuthToken, $ap.PolicyName)

        $ap | Add-Member -PassThru -MemberType NoteProperty -Name 'PolicyXml' -Value $x | 

            Select-Object -Property $p
    }
    end{}
}

function Invoke-ItmPreviouslyActivePolicyDownload
{
    param(
            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [System.Object]$ItmWebSeviceProxy = $null,

            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [String]$ItmAuthToken = $null,

            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [String]$PolicyName = $null,

            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [Int]$Version = $null,

            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [Int]$ActivationOrder = $null,

            [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [String]$DomainNameOrigin = $null,

            [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [System.DateTime]$DeactivationTime
         )
    
    begin
    {
        $p = 'DomainNameOrigin', 'PolicyName', 'Version', 'ActivationOrder', 'DeactivationTime', 'PolicyXml'
    }
    process
    {
        $ap = New-Object -TypeName psobject -Property @{'DomainNameOrigin' = $DomainNameOrigin; 'PolicyName' = $PolicyName; 'Version' = $Version; 'ActivationOrder' = $ActivationOrder; 'DeactivationTime' = $DeactivationTime }

        [xml]$x = $ItmWebSeviceProxy.DownloadPreviouslyActivePolicy($ItmAuthToken, $PolicyName, $Version, $ActivationOrder)

        $ap | Add-Member -PassThru -MemberType NoteProperty -Name 'PolicyXml' -Value $x | 

            Select-Object -Property $p
    }
    end{}
}

function Invoke-ItmStoredPolicyDownload
{
    param(
            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [System.Object]$ItmWebSeviceProxy = $null,

            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [String]$ItmAuthToken = $null,

            [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [String]$PolicyName = $null,

            [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [String]$DomainNameOrigin = $null,

            [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [String]$Version = $null,

            [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)]
            [ValidateNotNullOrEmpty()]
            [System.DateTime]$LastModifiedTime
         )

    begin
    {
        $p = 'DomainNameOrigin', 'PolicyName', 'Version', 'LastModifiedTime', 'PolicyXml'
    }

    process
    {
        $ap = New-Object -TypeName psobject -Property @{'DomainNameOrigin' = $DomainNameOrigin; 'PolicyName' = $PolicyName; 'Version' = $Version; 'LastModifiedTime' = $LastModifiedTime }

        [xml]$x = $ItmWebSeviceProxy.DownloadStoredPolicy($ItmAuthToken, $PolicyName)

        $ap | Add-Member -PassThru -MemberType NoteProperty -Name 'PolicyXml' -Value $x | 

            Select-Object -Property $p
    }

    end{}
}

function Save-ItmPolicyDownloadXml
{
    param(
            [parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [ValidateNotNullOrEmpty()]
            [System.Object[]]$ItmPolicyDownload = $null,
            
            [parameter(Mandatory=$false)]
            [String]$DirectoryName = $null

          )

    begin
    {
        $del = '__'
    }
    process
    {
        foreach($ipd in $ItmPolicyDownload)
        {
            $fn = $ItmPolicyDownload.DomainNameOrigin  + $del + $ItmPolicyDownload.Version + $del + $ItmPolicyDownload.PolicyName + '.xml'
        
            if($DirectoryName)
            {
                $fn = $DirectoryName + '\' + $fn
            }
            else
            {
                $fn = (Get-Location).Path + '\' + $fn
            }

            $fn = $fn -replace '\\\\', '\\'

            try
            {
                $ItmPolicyDownload.PolicyXml.save($fn)

                Write-Verbose -Message "Saving policy XML to $($fn)"
            }
            catch [System.Exception]
            {
                $Error[0]
            }
        }
    }
    end{}
}


function ConvertFrom-SecureToPlain {
    
    param( [Parameter(Mandatory=$true)][System.Security.SecureString] $SecurePassword )
    
    # Create a "password pointer"
    $PasswordPointer = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword)
    
    # Get the plain text version of the password
    $PlainTextPassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto($PasswordPointer)
    
    # Free the pointer
    [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($PasswordPointer)
    
    # Return the plain text password
    $PlainTextPassword    
}


#---need to add nRequired, nDesired
#
function ConvertTo-ItmResourceTable
{
    param(
            [parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [system.object[]]$ItmActivePolicyDownload = $null,
            [parameter(Mandatory=$false)]
            [switch]$ExtendedOutput = $false
         )

    begin
    {
        $NodeTable = $null
        $BranchTable = $null
        $ServerSetTable = $null
        $OverFlowServerTable = $null
        $ManagedServerTable = $null

        $dno = $null        
    
        $BasicP = 'label', 'dmo', 'branched', 'overflow', 'name', 'ip', 'monUrl'
        $ExtendedP = 'label', 'dmo', 'branched', 'overflow', 'name', 'id',  'ip', 'ttl', 'nRequired', 'nDesired', 'loadShare', 'shedFraction', 'mon', 'monUrl'
    }
    
    
    process
    {
        foreach($x in $ItmActivePolicyDownload)
        {

            if(($x.PolicyXml).POLICY.NODE)
            {
                $NodeTable = ($x.PolicyXml).SelectNodes("/POLICY/NODE") | ForEach-Object{$l = $_.label; $_.SelectNodes("RESOURCE/@id") | Select-Object -Property @{name = 'label'; expression = {$l}}, @{name = 'id'; expression ={ $_.Value}} }
            }

            if(($x.PolicyXml).POLICY.BRANCH)
            {
                $BranchTable = ($x.PolicyXml).SelectNodes("/POLICY/BRANCH")  | ForEach-Object{$l = $_.label; $_.SelectNodes("BRANCH//@id|NODE//@id") | Select-Object -Property @{name = 'label'; expression = {$l}}, @{name = 'id'; expression ={ $_.Value}} } 
            }

            if(($x.PolicyXml).POLICY.SERVERSET)
            {
                $ServerSetTable = ($x.PolicyXml).SelectNodes("/POLICY/SERVERSET") | Select-Object -Property id, nRequired, nDesired
            }

            if(($x.PolicyXml).POLICY.OVERFLOWSERVER)
            {
                $OverFlowServerTable = ($x.PolicyXml).SelectNodes("/POLICY/OVERFLOWSERVER") | Select-Object -Property name, id, @{name = 'ip'; expression  = { $_.ipCName}}, ttl, loadShare
            }

            if(($x.PolicyXml).POLICY.MANAGEDSERVER)
            {
                $ManagedServerTable = ($x.PolicyXml).SelectNodes("/POLICY/MANAGEDSERVER") | Select-Object -Property name, id, @{name = 'ip'; expression = {$_.ipAddr}}, ttl, loadShare, shedFraction, mon, monUrl
            }

            $o = $NodeTable |

                ForEach-Object{
            
                    $l = $_.label
                    $id = $_.id;
            
                    $ManagedServerTable | Where-Object{ $_.id -eq $id } |

                        Select-Object -Property @{name = 'label'; expression = {$l}}, @{name = 'branched'; expression = {$false}}, @{name = 'overflow'; expression = {$false}}, *
                }

            $o += $BranchTable |

                ForEach-Object{
            
                    $l = $_.label
                    $id = $_.id;
            
                    $ManagedServerTable | Where-Object{ $_.id -eq $id } |

                        Select-Object -Property @{name = 'label'; expression = {$l}}, @{name = 'branched'; expression = {$true}}, @{name = 'overflow'; expression = {$false}}, *
                }

            $o += $NodeTable |

                ForEach-Object{
            
                    $l = $_.label
                    $id = $_.id;
            
                    $OverFlowServerTable | Where-Object{ $_.id -eq $id } |

                        Select-Object -Property @{name = 'label'; expression = {$l}}, @{name = 'branched'; expression = {$false}}, @{name = 'overflow'; expression = {$true}}, @{name = 'shedFraction'; expression = {$null}}, @{name = 'mon'; expression = {$null}}, @{name = 'monUrl'; expression = {$null}}, *
                }

            $o += $BranchTable |

                ForEach-Object{
            
                    $l = $_.label
                    $id = $_.id;
            
                    $OverFlowServerTable | Where-Object{ $_.id -eq $id } |

                        Select-Object -Property @{name = 'label'; expression = {$l}}, @{name = 'branched'; expression = {$true}}, @{name = 'overflow'; expression = {$true}}, @{name = 'shedFraction'; expression = {$null}}, @{name = 'mon'; expression = {$null}}, @{name = 'monUrl'; expression = {$null}}, *
                }

            
            $ServerSetTable |

                ForEach-Object{

                    $nr = $_.nRequired
                    $nd = $_.nDesired
                    $id = $_.id

                    $o | Where-Object{ $_.id -eq $id } |

                        Add-Member -PassThru -MemberType NoteProperty -Name 'nRequired' -Value $nr | 

                            Add-Member -PassThru -MemberType NoteProperty -Name 'nDesired' -Value 'nDesired'

                        #Select-Object -Property *, @{name = 'nRequired'; expression = {$nr}}, @{name = 'nDesired'; expression = {'nDesired'}}
                }
            
            $null = $o | Add-Member -PassThru -MemberType NoteProperty -Name 'dmo' -Value $x.DomainNameOrigin

            #---Add ServerSet data here
            
            if($ExtendedOutput)
            {
                $o | Select-Object -Property $ExtendedP
            }
            else
            {
                $o | Select-Object -Property $BasicP
            }
        }
    } #--end of process block
    
    end{}
        
}

function Test-ItmResourceLiveness
{
    param(
            [parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [system.object[]]$ItmResourceTableRow = $null,
            
            [ValidateSet( 'Get', 'Head')]
            [String]$Method = 'Get',

            [System.Collections.Hashtable]$Headers = $null,
            
            [int]$WcTimeoutSec = 1
         )

    begin
    {
        $result = $null
        $Prop = 'label', 'dno', 'name', 'ip', 'monUrl'
        $ResultString = $null
        $live = $false
    }

    process
    {
        foreach($o in $ItmResourceTableRow)
        {
            $result = $null
            $ResultString = $null
            $live = $false
            
            try
            {
                $result = Invoke-WebRequest -UseBasicParsing -Uri $o.monUrl -TimeoutSec $WcTimeoutSec -Method $Method -Headers $Headers
                $ResultString = "StatusCode: $($result.StatusCode) StatusDescription: $($result.StatusDescription)"
                $live = $true
            }
            catch
            {
                $ResultString = $_.Exception.Message
            }

            $o |
                Select-Object -Property $Prop |
                    Add-Member -PassThru -MemberType NoteProperty -Name Live -Value $live |
                        Add-Member -PassThru -MemberType NoteProperty -Name Result -Value $ResultString
        }
    }

    end{}
}