TrackGpo_Smtp.psm1

function New-TrackGpoError_External {
    [CmdletBinding()]
    param(
        [parameter(Mandatory)]
        [String]$Message,

        [hashtable]$SmtpConfig = $Global:SmtpConfig
    )
    $Splat = @{}
    if (-not $SmtpConfig) { Write-Warning "No SMTP options configured. See Help for more details" }
    if (-not $SmtpConfig.ContainsKey("From")) { Write-Warning "No SMTP 'From' param configured. Skipping."; return }
    if (-not $SmtpConfig.ContainsKey("To")) { Write-Warning "No SMTP 'To' param configured. Skipping."; return }
    if (-not $SmtpConfig.ContainsKey("Subject")) { $Splat.Add("Subject", "Processing Invoke-GpoTracking has encountered an error at $(Get-Date)") }
    Send-MailMessage @SmtpConfig @Splat -Body $Message
}
function New-TrackGpoSmtpConfig {
    <#
.SYNOPSIS
This function creates an Smtp config object and stores it to the variable SmtpOptions for use with the other cmdlets in this module
 
.DESCRIPTION
The parameters for this command are pulled from the params from Send-MailMessage, which is what the other functions in this module use.
 
.PARAMETER SmtpServer
The SmtpServer to connect to when sending an email
 
.PARAMETER Port
The port to use for sending an email
 
.PARAMETER From
REQUIRED for Send-MailMessage. The address the email will come from
 
.PARAMETER To
REQUIRED for Send-MailMessage. The address the email will send to
 
.PARAMETER Cc
Other contacts to get a copy
 
.PARAMETER Bcc
Other contacts to get BCC'd
 
.PARAMETER ReplyTo
ReplyTo param for Send-MailMessage
 
.PARAMETER Subject
Static Subject to use instead of the default generated one
 
.PARAMETER UseSsl
Param to toggle UseSsl in Send-MailMessage
 
.PARAMETER Credential
Credentials to use for sending email via Send-MailMessage
 
.EXAMPLE
PS> New-TrackGpoSmtpConfig -SmtpServer "mail.domain.test" -From "admin@domain.test" -To "user@domain.test"
 
Creates an SmtpConfig hashtable and stores to $SmtpConfig. You can store the returned object and edit it further and overwrite the contents of that variable if you need to.
 
.NOTES
General notes
#>

    [CmdletBinding()]
    param (
        [parameter(Mandatory)]
        [string]$SmtpServer,
        [int]$Port = 22,
        [string]$From,
        [string[]]$To,
        [string[]]$Cc,
        [string[]]$Bcc,
        [string[]]$ReplyTo,
        [string]$Subject,
        [switch]$UseSsl,
        [switch]$BodyAsHtml,
        [PSCredential]$Credential
    )
    # Send-MailMessage params:
    # "Attachments",
    # "Bcc",
    # "Body",
    # "BodyAsHtml",
    # "Encoding",
    # "Cc",
    # "DeliveryNotificationOption",
    # "From",
    # "SmtpServer",
    # "Priority",
    # "ReplyTo",
    # "Subject",
    # "To",
    # "Credential",
    # "UseSsl",
    # "Port"
    $Splat = [ordered]@{}
    (
        "SmtpServer",
        "Port",
        "From",
        "To",
        "Cc",
        "Bcc",
        "ReplyTo",
        "Subject",
        "UseSsl",
        "BodyAsHtml",
        "Credential"
    ) | ForEach-Object {
        if ($PSBoundParameters.ContainsKey($_)) { $Splat.Add($_, $PSBoundParameters[$_]) }
    }
    $Splat.Port = $Port
    $Global:SmtpConfig = $Splat
    $Global:SmtpConfig
}
function New-TrackGpoTicket_External {
    <#
    .SYNOPSIS
    This is a sample external function for use with the TrackGpo module. It only outputs details to console.
 
    .DESCRIPTION
    When the TrackGpo module detects any GPO changes, it will call ALL modules who contain a function with this same name.
 
    It is up to you to make a function that emails or calls an API or whatever you want GPO changes to land to.
 
    If you only create a function and don't do it as part of a module,
    ensure that your function clobbers the namespace for that function.
    Meaning, make sure that running the command `New-TrackGpoTicket_External`
    will run your function and not any other module version instead.
    Remember, the LAST one to define the function is the one tha clobbers.
 
    .PARAMETER Type
    What type of GPO change has happened
 
    .PARAMETER GpoInfo
    A hashtable with the following properties:
        Title
        Created
        Modified
        GUID
        'GPO Status'
        'Enabled Links'
 
    .PARAMETER Diff
    This is only included when there are changes from one version of a GPO to another and contains the diff-style changes
    Ex:
    TODO
 
    .PARAMETER Stats
    A string of details about the changes
 
    .EXAMPLE
    New-TrackGpoTicket_External -Type Add -GpoInfo $GpoInfo
 
    .EXAMPLE
    New-TrackGpoTicket_External -Type Change -GpoInfo $GpoInfo -Diff $Diff
 
    .NOTES
    You may need to remove any non-ascii characters if your ticketing software sucks:
        | ForEach-Object {
        [system.Text.Encoding]::ASCII.Getstring((
                [system.Text.Encoding]::Default.GetBytes(($PSItem))
            ))
        }
 
    You may need to indent each line in your GpoInfo object with 4 spaces for your ticketing software to see it as code:
        ($GpoInfo | Format-Table -AutoSize | Out-String) -replace "(?m)^", " " -replace "\r"
    #>

    [CmdletBinding(SupportsShouldProcess)]
    param(
        [ValidateSet("Add", "Remove", "Change")]
        [parameter(Mandatory)]$Type,
        [parameter(Mandatory)]$GpoInfo,
        $Diff,
        $Stats,

        [hashtable]$SmtpConfig = $Global:SmtpConfig
    )
    if (-not $SmtpConfig) { Write-Warning "No SMTP options configured. See Help for more details" }
    if (-not $SmtpConfig.ContainsKey("From")) { Write-Warning "No SMTP 'From' param configured. Skipping."; return }
    if (-not $SmtpConfig.ContainsKey("To")) { Write-Warning "No SMTP 'To' param configured. Skipping."; return }


    if ($pscmdlet.ShouldProcess($GpoInfo.Title, "Notify about GPO change")) {
        $Splat = @{}
        switch ($Type) {
            "Add" {
                if (-not $SmtpConfig.ContainsKey("Subject")) { $Splat.Add("Subject", "A GPO has been added to your domain") }
                $Body = "Details of GPO:`n{0}" -f ([PSCustomObject]$GpoInfo | Format-List * | Out-String)
                Send-MailMessage @SmtpConfig @Splat -Body $Body
                $CommitMessage = "Add GPO: " + $GpoInfo.Title
            }
            "Remove" {
                if (-not $SmtpConfig.ContainsKey("Subject")) { $Splat.Add("Subject", "A GPO has been removed from your domain") }
                $Body = "Details of GPO:`n{0}" -f ([PSCustomObject]$GpoInfo | Format-List * | Out-String)
                Send-MailMessage @SmtpConfig @Splat -Body $Body
                $CommitMessage = "Remove GPO: " + $GpoInfo.Title
            }
            "Change" {
                if (-not $SmtpConfig.ContainsKey("Subject")) { $Splat.Add("Subject", "A GPO has been changed in your domain") }
                $Body = "Details of GPO:`n{0}`nChanges summary: {1}`nChanges present:`n{2}" -f ([PSCustomObject]$GpoInfo | Format-List * | Out-String),
                $Stats,
                ($Diff -join "`n")
                Send-MailMessage @SmtpConfig @Splat -Body $Body
                $CommitMessage = "Change GPO: " + $GpoInfo.Title
            }
        }
        # The output of this function will get saved as the Git commit message if you didn't disable Git.
        $CommitMessage
    }
}