Public/Discovery/Get-DiscoveryInfo.ps1

Function Get-DiscoveryInfo {
    ##
    <#
    .SYNOPSIS
    On-Premises Active Directory and Exchange Discovery script
     
    .EXAMPLE
    Get-DiscoveryInfo -ReportPath C:\PermsReports -PowerShell2 -ExchangeServer "ExServer01" -Verbose
    ***ONLY PS2: When running from PowerShell 2 (Exchange 2010 Server)***
 
    ***FIRST***: Be sure to dot-source the function with the below command (change the path):
    Get-ChildItem -Path "C:\scripts\Posh365\" -filter *.ps1 -Recurse | % { . $_.fullname }
    It is normal to see errors when running the above command, as some of the functions (that aren't needed here) do not support PS2
     
    #>

    [CmdletBinding(SupportsShouldProcess = $true)]
    param (
        [Parameter(Mandatory = $true)]
        [System.IO.FileInfo] $ReportPath,

        [Parameter()]
        [switch] $EstablishRemoteSessionToExchange,
        
        [Parameter()]
        [switch] $PowerShell2,
        
        [Parameter()]
        [string] $ExchangeServer,

        [Parameter()]
        [switch] $SkipSendAs,

        [Parameter()]
        [switch] $SkipSendOnBehalf,

        [Parameter()]
        [switch] $SkipFullAccess
    )

    Try {
        import-module activedirectory -ErrorAction Stop -Verbose:$false
    }
    Catch {
        Write-Host "This module depends on the ActiveDirectory module."
        Write-Host "Please download and install from https://www.microsoft.com/en-us/download/details.aspx?id=45520"
        throw
    }
    $RootPath = $env:USERPROFILE + "\ps\"
    $KeyPath = $Rootpath + "creds\"
    $User = $env:USERNAME

    Get-PSSession -ErrorAction SilentlyContinue | Where-Object {
        ($_.name -eq "OnPremExchage" -or $_.name -like "Session for implicit remoting module at*") -and ($_.availability -ne "Available" -and $_.State -ne "Opened")} | 
        ForEach-Object {Remove-PSSession $_.id}
    
    if ($PowerShell2) {
        Write-Warning "**************************************************************************************************"
        Write-Warning " You have selected -PowerShell2 which indicates that you are running this from PowerShell 2 "
        Write-Warning "If you haven't already, make sure to dot-source the functions with this command (change the Path):"
        Write-Warning " Get-ChildItem -Path `"C:\scripts\Posh365\`" -filter *.ps1 -Recurse | % { . `$_.fullname } "
        Write-Warning " It is normal to see errors when running the above command "
        Write-Warning "**************************************************************************************************"
        if (-not $ExchangeServer) {
            Write-Warning "********************************************************************************************"
            Write-Warning " Re-Run the command specifying the -ExchangeServer parameter "
            Write-Warning "ex. Get-DiscoveryInfo -ReportPath C:\PermsReports -PowerShell2 -ExchangeServer `"ExServer01`""
            Write-Warning " Script is terminating "
            Write-Warning "********************************************************************************************"
            throw
        }
        if (Get-PSSession -ErrorAction SilentlyContinue | Where-Object {
                ($_.name -eq "OnPremExchage" -or $_.name -like "Session for implicit remoting module at*") -and ($_.availability -ne "Available" -and $_.State -ne "Opened")}) {
            Connect-Exchange -ExchangeServer $ExchangeServer -ViewEntireForest -NoPrefix -NoMessageForPS2
        }
    }
    elseif ($EstablishRemoteSessionToExchange) {
        while (-not(Test-Path ($RootPath + "$($user).EXCHServer"))) {
            Select-ExchangeServer
        }
        $ExchangeServer = Get-Content ($RootPath + "$($user).EXCHServer")
        if (Get-PSSession -ErrorAction SilentlyContinue | Where-Object {
                ($_.name -eq "OnPremExchage" -or $_.name -like "Session for implicit remoting module at*") -and ($_.availability -ne "Available" -and $_.State -ne "Opened")}) {
            Connect-Exchange -ExchangeServer $ExchangeServer -ViewEntireForest -NoPrefix
        }
    }
    New-Item -ItemType Directory -Path $ReportPath -ErrorAction SilentlyContinue
    New-Item -ItemType Directory -Path (Join-Path $ReportPath "RawData") -ErrorAction SilentlyContinue
    New-Item -ItemType Directory -Path (Join-Path $ReportPath "ActiveDirectory") -ErrorAction SilentlyContinue
    New-Item -ItemType Directory -Path (Join-Path $ReportPath "Exchange") -ErrorAction SilentlyContinue
    $RawDataPath = Join-Path $ReportPath "RawData"
    $ADPath = Join-Path $ReportPath "ActiveDirectory"
    $ExchangePath = Join-Path $ReportPath "Exchange"

    $DomainNameHash = Get-DomainNameHash

    Write-Verbose "Retrieving Active Directory Objects that have at least one proxy address"
    $allADObjects = Get-ADObjectsWithProxyAddress -DomainNameHash $DomainNameHash

    Write-Verbose "Caching hash table. LogonName as Key and Values of DisplayName & UPN"
    $ADHash = $allADObjects | Get-ADHash

    Write-Verbose "Caching hash table for Groups. LogonName as Key and Values of DisplayName & UPN"
    $ADHashDG = $allADObjects | Get-ADHashDG

    Write-Verbose "Caching hash table. DN as Key and Values of DisplayName, UPN & LogonName"
    $ADHashDN = $allADObjects | Get-ADHashDN

    Write-Verbose "Caching hash table for Groups. DN as Key and Values of DisplayName, UPN & LogonName"
    $ADHashDGDN = $AllADObjects | Get-ADHashDGDN

    Write-Verbose "Caching hash table. CN as Key and Values of DisplayName, UPN & LogonName"
    $ADHashCN = $allADObjects | Get-ADHashCN
    
    Write-Verbose "Retrieving all Active Directory Users"
    $allADUsers = Get-ActiveDirectoryUser -DetailedReport

    Write-Verbose "Exporting all Active Directory Users to RawADUsers.csv"
    $allADUsers | Export-csv (Join-Path -Path $RawDataPath -ChildPath "RawADUsers.csv") -NoTypeInformation -Encoding UTF8

    Write-Verbose "Retrieving all Exchange Mailboxes"
    $allMailbox = Get-ExchangeMailbox -DetailedReport

    Write-Verbose "Exporting all Exchange Mailboxes to RawExchangeMailboxes.csv"
    $allMailbox | Export-csv (Join-Path -Path $RawDataPath -ChildPath "RawExchangeMailboxes.csv") -NoTypeInformation -Encoding UTF8

    Write-Verbose "Retrieving distinguishedname's of all Exchange Mailboxes"
    $allMailboxDN = $allMailbox | Select -expandproperty distinguishedname

    Write-Verbose "Retrieving all Exchange Distribution Groups"
    $allGroups = Get-ExchangeDistributionGroup -DetailedReport

    Write-Verbose "Exporting all Exchange Distribution Groups to file ExchangeDistributionGroups.csv"
    $allGroups | Export-csv (Join-Path -Path $RawDataPath -ChildPath "RawExchangeDistributionGroups.csv") -NoTypeInformation -Encoding UTF8

    Write-Verbose "Exporting all Exchange Distribution Groups Members to file DistributionGroupMembers.csv"
    $allGroups | Export-CsvData -JoinType and -Match "." -FindInColumn "MembersName" -ReportPath $ExchangePath -fileName "DistributionGroupMembers.csv"

    Write-Verbose "Retrieving distinguishedname's of all Exchange Distribution Groups"
    $allGroupsDN = $allGroups | Select -expandproperty distinguishedname

    $MailboxProperties = @(
        'DisplayName', 'OU', 'RecipientTypeDetails', 'UserPrincipalName', 'PrimarySmtpAddress', 'Identity', 'Alias'
        'ForwardingAddress', 'ForwardingSmtpAddress', 'LitigationHoldDate', 'AccountDisabled', 'DeliverToMailboxAndForward'
        'HiddenFromAddressListsEnabled', 'LitigationHoldEnabled', 'LitigationHoldDuration'
        'LitigationHoldOwner', 'Office', 'RetentionPolicy', 'WindowsEmailAddress', 'ArchiveName', 'AcceptMessagesOnlyFrom'
        'AcceptMessagesOnlyFromDLMembers', 'AcceptMessagesOnlyFromSendersOrMembers', 'RejectMessagesFrom', 'RejectMessagesFromDLMembers'
        'RejectMessagesFromSendersOrMembers', 'InPlaceHolds', 'x500', 'EmailAddresses'
    )
    
    $GroupProperties = @(
        'DisplayName', 'OU', 'RecipientTypeDetails', 'Alias', 'ManagedBy', 'GroupType', 'Identity', 'PrimarySmtpAddress', 'WindowsEmailAddress'
        'AcceptMessagesOnlyFromSendersOrMembers', 'x500', 'EmailAddresses'
    )

    Write-Verbose "Exporting all ADUser with Inheritance Broken to InheritanceBroken.csv"
    $allADUsers | where {$_.InheritanceBroken -eq "True"} | Select DisplayName, InheritanceBroken, OU, PrimarySmtpAddress, UserPrincipalName |
        Export-csv (Join-Path -Path $ADPath -ChildPath "InheritanceBroken.csv") -NoTypeInformation -Encoding UTF8

    Write-Verbose "Exporting all Exchange Mailboxes to ExchangeMailboxes.csv"
    $allMailbox | Select $MailboxProperties | 
        Export-csv (Join-Path -Path $ExchangePath -ChildPath "ExchangeMailboxes.csv") -NoTypeInformation -Encoding UTF8

    Write-Verbose "Exporting all smtp addresses for Exchange Mailboxes"
    $allMailbox | Export-CsvData -JoinType and -Match "smtp:" -FindInColumn "EmailAddresses" -ReportPath "$ExchangePath" -fileName "MailboxSmtpAddresses.csv"
    
    Write-Verbose "Exporting all sip addresses for Exchange Mailboxes"
    $allMailbox | Export-CsvData -JoinType and -Match "sip:" -FindInColumn "EmailAddresses" -ReportPath "$ExchangePath" -fileName "MailboxSipAddresses.csv"
    
    Write-Verbose "Exporting all Exchange Distribution Groups to ExchangeDistributionGroups.csv"
    $allGroups | Select $GroupProperties | 
        Export-csv (Join-Path -Path $ExchangePath -ChildPath "ExchangeDistributionGroups.csv") -NoTypeInformation -Encoding UTF8

    Write-Verbose "Exporting all smtp addresses for Exchange Distribution Groups"
    $allGroups | Export-CsvData -JoinType and -Match "smtp:" -FindInColumn "EmailAddresses" -ReportPath "$ExchangePath" -fileName "DistributionGroupSmtpAddresses.csv"
        
    $FwdSelect = @('DisplayName', 'UserPrincipalName', 'ForwardingAddress')
    $FwdSelectCalc = @(
        @{n = 'FwdDisplayName'; e = {$ADHashCN["$($_.ForwardingAddress)"].DisplayName}},
        @{n = 'FwdPrimarySmtpAddress'; e = {$ADHashCN["$($_.ForwardingAddress)"].PrimarySmtpAddress}},
        @{n = 'FwdmsExchRecipientTypeDetails'; e = {$ADHashCN["$($_.ForwardingAddress)"].msExchRecipientTypeDetails}},
        @{n = 'FwdmsExchRecipientDisplayType'; e = {$ADHashCN["$($_.ForwardingAddress)"].msExchRecipientDisplayType}}
    )

    Write-Verbose "Exporting Mailboxes with Forwarding Addresses to file FowardingAddress.csv"
    $allMailbox | Where-Object {$_.ForwardingAddress} | Select @($FwdSelect + $FwdSelectCalc) |
        Export-csv (Join-Path $ExchangePath -ChildPath "FowardingAddress.csv") -NoTypeInformation -Encoding UTF8

    $HiddenSelect = @('DisplayName', 'UserPrincipalName', 'alias', 'HiddenFromAddressListsEnabled')

    Write-Verbose "Exporting Mailboxes that are Hidden from the GAL to file HiddenFromGAL.csv"
    $allMailbox | Where-Object {$_.HiddenFromAddressListsEnabled -eq $TRUE} | Select $HiddenSelect |
        Export-csv (Join-Path $ExchangePath -ChildPath "HiddenFromGAL.csv") -NoTypeInformation -Encoding UTF8

    if (-not $SkipSendAs) {
        Write-Verbose "Getting SendAs permissions for each mailbox and writing to file SendAsPerms.csv"
        $allMailboxDN | Get-SendAsPerms -ADHashDN $ADHashDN -ADHash $ADHash  | Select Object, UPN, Granted, GrantedUPN, Permission |
            Export-csv (Join-Path $ExchangePath -ChildPath "SendAsPerms.csv") -NoTypeInformation -Encoding UTF8
    }
    
    if (-not $SkipSendOnBehalf) {
        Write-Verbose "Getting SendOnBehalf permissions for each mailbox and writing to file SendOnBehalfPerms.csv"
        $allMailboxDN | Get-SendOnBehalfPerms -ADHashCN $ADHashCN | Select Object, UPN, Granted, GrantedUPN, Permission |
            Export-csv (Join-Path $ExchangePath -ChildPath "SendOnBehalfPerms.csv") -NoTypeInformation -Encoding UTF8
    }
    
    if (-not $SkipFullAccess) {
        Write-Verbose "Getting FullAccess permissions for each mailbox and writing to file FullAccessPerms.csv"
        $allMailboxDN | Get-FullAccessPerms -ADHashDN $ADHashDN -ADHash $ADHash | Select Object, UPN, Granted, GrantedUPN, Permission |
            Export-csv (Join-Path $ExchangePath -ChildPath "FullAccessPerms.csv") -NoTypeInformation -Encoding UTF8
    }

    $AllPermissions = $null
    $Report = $ReportPath.ToString()
    $Report = $Report.TrimEnd('\') + "\*"
    $AllPermissions = Get-ChildItem -Path $Report -Include "SendAsPerms.csv", "SendOnBehalfPerms.csv", "FullAccessPerms.csv" -Exclude "AllPermissions.csv" | % {
        Import-Csv $_
    }
    
    $AllPermissions | Export-Csv (Join-Path $ExchangePath -ChildPath "AllPermissions.csv") -NoTypeInformation -Encoding UTF8
    Write-Verbose "Combined all Mailbox Delegate Permission CSV's into a single file named, AllPermissions.csv"

    Write-Verbose "Exporting Distribution Group Send-as Delegate Permission to file DGSendAsPerms.csv"
    $allGroupsDN | Get-DGSendAsPerms -ADHashDGDN $ADHashDGDN -ADHashDG $ADHashDG  | Select Object, PrimarySMTP, Granted, GrantedUPN, GrantedSMTP, Permission |
        Export-csv (Join-Path $ExchangePath -ChildPath "DGSendAsPerms.csv") -NoTypeInformation

}