tak.exchange.psm1
#region Helpers function New-ExchangeAutodiscoverReport { [CmdletBinding()] param ( [psobject] $InputObject, [System.IO.FileInfo] $FileName = (Join-Path -Path $($env:temp) -ChildPath "ExchangeAutodiscoverReport.html") ) begin { Remove-Item -Path $FileName -ErrorAction SilentlyContinue } process { foreach($key in (Get-Member -InputObject $InputObject -MemberType NoteProperty).Name) { $html += $InputObject.$key.Protocol | ConvertTo-Html -As List -Fragment } $html | Set-Content -Path $FileName Write-Host "report at $FileName" } end { } } function Get-XmlBody([string]$EmailAddress){ [xml]@" <Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006"> <Request> <EMailAddress>$EmailAddress</EMailAddress> <AcceptableResponseSchema>http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a</AcceptableResponseSchema> </Request> </Autodiscover> "@ } function Get-AutodiscoverURI { param ( [string]$EmailAddress, [string]$ComputerName, [switch]$ExcludeExplicitO365Endpoint ) $domainName = $EmailAddress -split "@" | Select-Object -Last 1 $out = @{ "root" = "https://$domainName/autodiscover/autodiscover.xml"; "autodiscover" = "https://autodiscover.$domainName/autodiscover/autodiscover.xml"; } if($adSrv = Get-AutodiscoverSRV -domainName $domainName) { $out.Add("srv",$adSrv) } if($ComputerName) { $out.Add("uri","https://$ComputerName/autodiscover/autodiscover.xml") } if (-not($ExcludeExplicitO365Endpoint)) { $out.Add("o365","https://autodiscover-s.outlook.com/autodiscover/autodiscover.xml") } $out } function Get-AutodiscoverResponse { [CmdletBinding()] param( [string]$uri, [xml]$body, [int]$Timeout = 2, [pscredential]$Credential ) $params = @{ "uri" = $uri "Credential" = $Credential "Method" = "post" "Body" = $body "Headers" = @{"content-type"="text/xml"} "DisableKeepAlive" = $true "TimeoutSec" = $Timeout } try { Write-Verbose "Trying to connect to $uri" $adPayload = Invoke-RestMethod @params $adPayload.Autodiscover.Response.Account } catch { Write-Verbose "Could not connect to $uri" } } function Get-AutodiscoverSRV([string]$domainName) { $dns = Resolve-DnsName -Name "_autodiscover._tcp.$domainName" -Type SRV -ErrorAction SilentlyContinue | Where-Object {$_.Type -eq "SRV" -and $_.Port -eq 443} if($dns) { "https://$($dns.NameTarget)/autodiscover/autodiscover.xml" } } #endregion Helpers #region Exchange function Test-ExchangeAutodiscover { <# .SYNOPSIS Test Exchange Autodiscover Web Service. .DESCRIPTION This function tests the Exchange Autodiscover Web Serivce for a given Emailaddress. If ComputerName is not specified, the function tries to look up the Autodiscover service using the Outlook Clients logic. Locally cached and SCP data are not evaluated. .EXAMPLE PS C:\> Test-ExchangeAutodiscover thomas@ntsystems.it -Credential (Get-Credential) This example tests the Autodiscover service for the given mailbox. It will query dns for autodiscover.ntsystems.it and _autodiscover._tcp.ntsystems.it. It will then try to retrieve an Autodiscover payload from https://ntsystems.it, https://autodiscover.ntsystems.it and the Office 365 endpoint. .OUTPUTS [psobject] #> [CmdletBinding(HelpUri = 'https://ntsystems.it/PowerShell/TAK/test-exchangeautodiscover/')] param ( [string] $EmailAddress, [string] $ComputerName, [pscredential] $Credential, [switch] $ExcludeExplicitO365Endpoint, [System.IO.FileInfo] $Report ) begin { # Get URI and XML Body for reuqest $adURIs = Get-AutodiscoverURI @PSBoundParameters $body = Get-XMLBody @PSBoundParameters } process { # Create an empty dictionary to store $out = @{} foreach($key in $adURIs.keys){ Write-Verbose "Testing $key domain for $EmailAddress : $($adURIs[$key])" $r = Get-AutodiscoverResponse -uri $adURIs[$key] -Credential $Credential -body $body if($r) { $out.add($key,$r) } } # create a new object and write it to the pipeline $global:ExchangeAutodiscoverResults = New-Object -TypeName psobject -Property $out | Add-Member -TypeName 'System.TAK.ExchangeAutoDiscover' -PassThru Write-Output $global:ExchangeAutodiscoverResults Write-Host "Results are available through the global variable `$ExchangeAutodiscoverResults for your convenience.`n" if($Report) { New-ExchangeAutodiscoverReport -InputObject $global:ExchangeAutodiscoverResults -FileName $Report } } end { } } function Get-MxRecord { <# .SYNOPSIS Get MX Records for a domain. .DESCRIPTION Uses Resolve-DnsName to get MX Records, Priority and the IP Address of the records. .EXAMPLE PS C:\> Get-MxRecord ntsystems.it This example gets the MX record for the domain ntsystems.it. .INPUTS [string] .OUTPUTS [Selected.Microsoft.DnsClient.Commands.DnsRecord_MX] #> [CmdletBinding(HelpUri = 'https://ntsystems.it/PowerShell/TAK/get-mxrecord/')] param ( [Parameter(ValueFromPipeline=$true)] [string] $Domain, [System.Net.IPAddress] $Server ) begin { $param = @{ ErrorAction="SilentlyContinue" QuickTimeout=$True } if($Server) { $param.Add("Server",$Server) } } process { $mx = Resolve-DnsName -Name $domain -Type MX -ErrorAction SilentlyContinue | Where-Object Type -eq "MX" if ($mx) { $rec = $mx | Select-Object -Property NameExchange,Preference,@{ Name = "IPAddress" Expression = { Resolve-DnsName -Name $_.NameExchange -Type A_AAAA @param | Select-Object -ExpandProperty IPAddress } } $rec | Select-Object -Property *,@{ Name = "PTR" Expression = { $_.IpAddress | ForEach-Object { Resolve-DnsName -Name $_ -Type PTR @param | Select-Object -ExpandProperty NameHost } } } } } } #endregion #region Test ADFS function Test-FederationService { <# .Synopsis Test the ADFS web service .DESCRIPTION This function uses Invoke-RestMethod to test if the federation service metadata can be retrieved from a given server. .EXAMPLE Test-FederationService -ComputerName fs.uclab.eu This example gets federation service xml information over the server fs.uclab.eu #> [CmdletBinding(HelpUri = 'https://ntsystems.it/PowerShell/TAK/Test-FederationService/')] param( # Specifies the name of the federation server [Parameter(Mandatory=$true)] [validateLength(3,255)] [validatepattern("\w\.\w")] [string] [Alias("Server")] $ComputerName ) $uri = "https://$ComputerName/FederationMetadata/2007-06/FederationMetadata.xml" # "adfs/ls/idpinitiatedsignon.htm" try { $webRequest = Invoke-RestMethod -Uri $uri -ErrorAction Stop Write-Verbose $webRequest } catch { Write-Warning "Could not connect to $uri error $_" return } $out = [ordered]@{ "entityID" = $webRequest.entitydescriptor.entityID "xmlns" = $webRequest.entitydescriptor.xmlns "Roles" = @{ "type" = $webRequest.entitydescriptor.RoleDescriptor.type "ServiceDisplayName" = $webRequest.entitydescriptor.RoleDescriptor.ServiceDisplayName } } # Create a custom object and add a custom TypeName for formatting before writing to pipeline Write-Output (New-Object -TypeName psobject -Property $out) } #endregion Test ADFS |