functions/Send-D365LBDUpdateMSTeams.ps1
function Send-D365LBDUpdateMSTeams { <# .SYNOPSIS Created to Send D365 updates to MSTeams .DESCRIPTION Created to Send D365 updates to MSTeams .EXAMPLE Send-D365LBDUpdateMSTeams -messageType "StatusReport" -MSTeamsURI "htts://fakemicrosoft.office.com/webhookb2/98984684987156465-4654/incominginwebhook/ea5s6d4sa6" -config $config .EXAMPLE Send-D365LBDUpdateMSTeams -messageType "BuildPrepStarted" -MSTeamsURI "htts://fakemicrosoft.office.com/webhookb2/98984684987156465-4654/incominginwebhook/ea5s6d4sa6" -config $config -build 'FakeBuildNumber' .EXAMPLE Send-D365LBDUpdateMSTeams -messageType "BuildPrepped" -MSTeamsURI "htts://fakemicrosoft.office.com/webhookb2/98984684987156465-4654/incominginwebhook/ea5s6d4sa6" -config $config -CustomModuleName 'CUS' .EXAMPLE Send-D365LBDUpdateMSTeams -messageType "BuildStart" -MSTeamsURI "htts://fakemicrosoft.office.com/webhookb2/98984684987156465-4654/incominginwebhook/ea5s6d4sa6" -MSTeamsBuildName '1.1.2021' -CustomModuleName 'CUS' .EXAMPLE Send-D365LBDUpdateMSTeams -messageType "BuildComplete" -MSTeamsURI "htts://fakemicrosoft.office.com/webhookb2/98984684987156465-4654/incominginwebhook/ea5s6d4sa6" -MSTeamsBuildName '1.1.2021' -CustomModuleName 'CUS' .EXAMPLE Send-D365LBDUpdateMSTeams -messageType "PlainText" -MSTeamsURI "htts://fakemicrosoft.office.com/webhookb2/98984684987156465-4654/incominginwebhook/ea5s6d4sa6" -PlainTextTitle 'TITLE' -PlainTextMessage 'Message' .EXAMPLE Send-D365LBDUpdateMSTeams -messageType "StatusReport" -MSTeamsURI "htts://fakemicrosoft.office.com/webhookb2/98984684987156465-4654/incominginwebhook/ea5s6d4sa6" -config $config -MSTeamsExtraDetailsTitle 'FactTitle' -MSTeamsExtraDetails 'Fact Text' -MSTeamsExtraDetailsURI 'http://google.com' .EXAMPLE Send-D365LBDUpdateMSTeams -messageType "PlainText" -MSTeamsURI "htts://fakemicrosoft.office.com/webhookb2/98984684987156465-4654/incominginwebhook/ea5s6d4sa6" -PlainTextTitle 'TITLE' -PlainTextMessage 'Message' #> [alias("Send-D365UpdateMSTeams")] [CmdletBinding()] param ( [PSFComputer]$ComputerName = "$env:COMPUTERNAME", [Parameter(ParameterSetName = 'Config', ValueFromPipeline = $True)] [psobject]$Config, [string]$MSTeamsURI, [string]$MSTeamsExtraDetailsURI, [string]$MSTeamsExtraDetails, [string]$MSTeamsExtraDetailsTitle, [string]$MSTeamsBuildName, [string]$MSTeamsBuildURL, [string]$MSTeamsCustomStatus, [string]$MessageType, [string]$CustomModuleName, [string]$EnvironmentName, [string]$EnvironmentURL, [string]$PlainTextMessage, [string]$PlainTextTitle, [switch]$StatusReportIgnorePermissionErrors, [string]$PlaintTextStatus ) BEGIN { } PROCESS { switch ( $MessageType) { "PreDeployment" { Stop-PSFFunction -Message "PreDeployment use Set-D365LBDOptions" } "PostDeployment" { Stop-PSFFunction -Message "PostDeployment use Set-D365LBDOptions" } "BuildStart" { $status = 'Build Started' } "BuildComplete" { $status = 'Build Completed' } "BuildPrepStarted" { $status = 'Build Prep Started' } "BuildPrepped" { $status = 'Build Prepped' } "StatusReport" { $Status = "Status Report" } "PlainText" {$Status = $PlaintTextStatus } default { Stop-PSFFunction -Message "Message type $MessageType is not supported" } } if ($MSTeamsCustomStatus) { $status = "$MSTeamsCustomStatus" } if (!$MSTeamsURI) { Write-PSFMessage -Level VeryVerbose -Message "MSTeamsURI not defined attemping to find in config" if (!$CustomModuleName) { if (!$Config) { $Config = Get-D365LBDConfig -ComputerName $ComputerName -CustomModuleName $CustomModuleName -HighLevelOnly } } else { if (!$Config) { $Config = Get-D365LBDConfig -ComputerName $ComputerName -HighLevelOnly } } $AgentShareLocation = $config.AgentShareLocation $EnvironmentAdditionalConfig = get-childitem "$AgentShareLocation\scripts\D365FOLBDAdmin\AdditionalEnvironmentDetails.xml" [xml]$EnvironmentAdditionalConfigXML = get-content $EnvironmentAdditionalConfig.FullName $MSTeamsURIS = $EnvironmentAdditionalConfigXML.D365LBDEnvironment.Communication.Webhooks.Webhook | Where-Object { $_.Type.'#text'.Trim() -eq "MSTeams" } if (!$MSTeamsURI -and !$MSTeamsURIS) { Stop-PSFFunction -Message "Error: MS Teams URI not specified and can't find one in configs" -EnableException $true -Cmdlet $PSCmdlet } } if (!$MSTeamsURIS) { $MSTeamsURIS = $MSTeamsURI } if (!$CustomModuleName -and $MessageType -eq "BuildPrepped") { if (!$Config) { $Config = Get-D365LBDConfig -ComputerName $ComputerName -HighLevelOnly } $CustomModuleName = $Config.CustomModuleName if (!$CustomModuleName -and !$MSTeamsBuildName) { Stop-PSFFunction -Message "ERROR: CustomModuleName NOT DEFINED and MSTeamsBuildName NOT DEFINED." -EnableException $true -Cmdlet $PSCmdlet } if (!$CustomModuleName -and $MSTeamsBuildName) { $CustomModuleName = "CustomModule" } } if (($CustomModuleName) -and $MessageType -eq "BuildPrepped" -and ($MSTeamsBuildName)) { ## BUILD PREPPED Beginning Write-PSFMessage -Level VeryVerbose -Message "MessageType is: BuildPrepped - BuildName has been defined ($MSTeamsBuildName)" if (!$EnvironmentName) { if (!$CustomModuleName -and $CustomModuleName -ne "CustomModule") { if (!$Config) { $Config = Get-D365LBDConfig -ComputerName $ComputerName -CustomModuleName $CustomModuleName -HighLevelOnly } } else { if (!$Config) { $Config = Get-D365LBDConfig -ComputerName $ComputerName -HighLevelOnly } } $LCSEnvironmentName = $Config.LCSEnvironmentName $clienturl = $Config.clienturl $LCSEnvironmentURL = $Config.LCSEnvironmentURL } if (!$EnvironmentName) { $bodyjson = @" { "@type": "MessageCard", "@context": "http://schema.org/extensions", "themeColor": "ff0000", "title": "$LCSEnvironmentName $status", "summary": "$LCSEnvironmentName $status", "sections": [{ "facts": [{ "name": "Environment", "value": "[$LCSEnvironmentName]($clienturl)" },{ "name": "Build Version/Name", "value": "$MSTeamsBuildName" },{ "name": "LCS", "value": "[LCS]($LCSEnvironmentURL)" }], "markdown": true }] } "@ } else { $bodyjson = @" { "@type": "MessageCard", "@context": "http://schema.org/extensions", "themeColor": "ff0000", "title": "$EnvironmentName $status ", "summary": "$EnvironmentName $status", "sections": [{ "facts": [{ "name": "Environment", "value": "[$EnvironmentName]($EnvironmentURL)" },{ "name": "Build Version/Name", "value": "$MSTeamsBuildName" }], "markdown": true }] } "@ } $bodyjsonformed = 1 } ## if (($CustomModuleName) -and $MessageType -eq "BuildPrepped" -and $bodyjsonformed -ne 1) { Write-PSFMessage -Level VeryVerbose -Message "MessageType is: BuildPrepped - BuildName has NOT been defined" if (!$CustomModuleName -and !$Config) { $Config = Get-D365LBDConfig -ComputerName $ComputerName -CustomModuleName $CustomModuleName -HighLevelOnly } else { if (!$Config) { $Config = Get-D365LBDConfig -ComputerName $ComputerName -HighLevelOnly } } $Prepped = Export-D365LBDAssetModuleVersion -CustomModuleName $CustomModuleName -config $Config if ($Prepped) { if ($Prepped.Count -eq 1) { Write-PSFMessage -Message "Found a prepped build: $Prepped" -Level VeryVerbose $LCSEnvironmentName = $Config.LCSEnvironmentName $clienturl = $Config.clienturl $LCSEnvironmentURL = $Config.LCSEnvironmentURL $bodyjson = @" { "@type": "MessageCard", "@context": "http://schema.org/extensions", "themeColor": "ff0000", "title": "$status $LCSEnvironmentName", "summary": "$status $LCSEnvironmentName", "sections": [{ "facts": [{ "name": "Environment", "value": "[$LCSEnvironmentName]($clienturl)" },{ "name": "Build Version/Name", "value": "$Prepped" },{ "name": "LCS", "value": "[LCS]($LCSEnvironmentURL)" }], "markdown": true }] } "@ $bodyjsonformed = 1 } else { foreach ($build in $Prepped) { Write-PSFMessage -Message "Found multiple prepped builds including: $build" -Level VeryVerbose } } } ## if preppfound end starting else to find the latest built if ($bodyjsonformed -ne 1) { Write-PSFMessage -Level VeryVerbose -Message "No newly prepped build found" ##add logic to grab latest $MSTeamsBuildName = $Config.LastFullyPreppedCustomModuleAsset if ($EnvironmentName) { $LCSEnvironmentName = $EnvironmentName } else { $LCSEnvironmentName = $config.LCSEnvironmentName } $clienturl = $Config.clienturl $LCSEnvironmentURL = $Config.LCSEnvironmentURL $Prepped = $config.LastFullyPreppedCustomModuleAsset if (!$MSTeamsBuildName) { Write-PSFMessage -Message "Can't find Version removing from json" $bodyjson = @" { "@type": "MessageCard", "@context": "http://schema.org/extensions", "themeColor": "ff0000", "title": "$LCSEnvironmentName $status", "summary": "$LCSEnvironmentName $status", "sections": [{ "facts": [{ "name": "Environment", "value": "[$LCSEnvironmentName]($clienturl)" },{ "name": "LCS", "value": "[LCS]($LCSEnvironmentURL)" }], "markdown": true }] } "@ } else { $bodyjson = @" { "@type": "MessageCard", "@context": "http://schema.org/extensions", "themeColor": "ff0000", "title": "$LCSEnvironmentName $status", "summary": "$LCSEnvironmentName $status", "sections": [{ "facts": [{ "name": "Environment", "value": "[$LCSEnvironmentName]($clienturl)" },{ "name": "Build Version/Name", "value": "$MSTeamsBuildName" },{ "name": "LCS", "value": "[LCS]($LCSEnvironmentURL)" }], "markdown": true }] } "@ } } } ## end of build prep if ($MessageType -eq "PlainText") { Write-PSFMessage -Level VeryVerbose -Message "MessageType is: Plain Text Message" if ($PlainTextTitle) { Write-PSFMessage -Level VeryVerbose -Message "Plain Text Message with Custom Title" $bodyjson = @" { "title":"$($("$PlainTextTitle $status").trim())", "text":"$PlainTextMessage" } "@ } else { Write-PSFMessage -Level VeryVerbose -Message "Plain Text Message" $bodyjson = @" { "title":"$($("D365 Update $status").trim())", "text":"$PlainTextMessage" } "@ } if ($MSTeamsExtraDetails) { $bodyjson = @" { "@type": "MessageCard", "@context": "http://schema.org/extensions", "themeColor": "ff0000", "title": "$PlainTextTitle $status", "summary": "$PlainTextTitle $PlainTextMessage", "sections": [{ "facts": [{ "name": "$PlainTextTitle", "value": "$PlainTextMessage" }], "markdown": true }] } "@ } } ## PLAIN TEXT END if ($MessageType -eq "BuildStart") { Write-PSFMessage -Message "MessageType is: BuildStart" -Level VeryVerbose if (!$MSTeamsBuildName) { Stop-PSFFunction -Message "Error: MSTEAMSBuildName needs to be defined" -EnableException $true -Cmdlet $PSCmdlet } else { if ($MSTeamsBuildURL) { $bodyjson = @" { "@type": "MessageCard", "@context": "http://schema.org/extensions", "themeColor": "ff0000", "title": "$status", "summary": "$status", "sections": [{ "facts": [{ "name": "Build Version", "value": "[$MSTeamsBuildName]($MSTeamsBuildURL)" }], "markdown": true }] } "@ } else { $bodyjson = @" { "@type": "MessageCard", "@context": "http://schema.org/extensions", "themeColor": "ff0000", "title": "$status", "summary": "$status", "sections": [{ "facts": [{ "name": "Build Version", "value": "$MSTeamsBuildName" }], "markdown": true }] } "@ } } } if ($MessageType -eq "BuildComplete") { Write-PSFMessage -Message "MessageType is: BuildComplete" -Level VeryVerbose if (!$MSTeamsBuildName) { Stop-PSFFunction -Message "Error: MSTEAMSBuildName needs to be defined" -EnableException $true -Cmdlet $PSCmdlet } else { if ($MSTeamsBuildURL) { $bodyjson = @" { "@type": "MessageCard", "@context": "http://schema.org/extensions", "themeColor": "ff0000", "title": "$status", "summary": "$status", "sections": [{ "facts": [{ "name": "Build Version", "value": "[$MSTeamsBuildName]($MSTeamsBuildURL)" }], "markdown": true }] } "@ } else { $bodyjson = @" { "@type": "MessageCard", "@context": "http://schema.org/extensions", "themeColor": "ff0000", "title": "$status", "summary": "$status", "sections": [{ "facts": [{ "name": "Build Version", "value": "$MSTeamsBuildName" }], "markdown": true }] } "@ } } } if ($MessageType -eq "BuildPrepStarted") { Write-PSFMessage -Message "MessageType is: Build Prep Started" -Level VeryVerbose if (!$CustomModuleName) { if (!$Config) { $Config = Get-D365LBDConfig -ComputerName $ComputerName -CustomModuleName $CustomModuleName -HighLevelOnly } } else { if (!$Config) { $Config = Get-D365LBDConfig -ComputerName $ComputerName -HighLevelOnly } } $LCSEnvironmentName = $Config.LCSEnvironmentName $clienturl = $Config.clienturl $LCSEnvironmentURL = $Config.LCSEnvironmentURL if (!$MSTeamsBuildName) { Stop-PSFFunction -Message "Error: MSTEAMSBuildName needs to be defined" -EnableException $true -Cmdlet $PSCmdlet } $bodyjson = @" { "@type": "MessageCard", "@context": "http://schema.org/extensions", "themeColor": "ff0000", "title": "$LCSEnvironmentName $status", "summary": "$LCSEnvironmentName $status", "sections": [{ "facts": [{ "name": "Environment", "value": "[$LCSEnvironmentName]($clienturl)" },{ "name": "Build Version/Name", "value": "$MSTeamsBuildName" },{ "name": "LCS", "value": "[LCS]($LCSEnvironmentURL)" }], "markdown": true }] } "@ } if ($MessageType -eq "StatusReport") { Write-PSFMessage -Message "MessageType is: StatusReport" -Level VeryVerbose if (!$CustomModuleName) { if (!$Config) { $Config = Get-D365LBDConfig -ComputerName $ComputerName } } else { if (!$Config) { $Config = Get-D365LBDConfig -ComputerName $ComputerName -CustomModuleName $CustomModuleName } } [int]$count = 0 while (!$connection) { do { $OrchestratorServerName = $Config.OrchestratorServerNames | Select-Object -First 1 -Skip $count Write-PSFMessage -Message "Verbose: Reaching out to $OrchestratorServerName to try and connect to the service fabric" -Level Verbose $SFModuleSession = New-PSSession -ComputerName $OrchestratorServerName if (!$module) { $module = Import-Module -Name ServiceFabric -PSSession $SFModuleSession } Write-PSFMessage -Message "-ConnectionEndpoint $($config.SFConnectionEndpoint) -X509Credential -FindType FindByThumbprint -FindValue $($config.SFServerCertificate) -ServerCertThumbprint $($config.SFServerCertificate) -StoreLocation LocalMachine -StoreName My" -Level Verbose $connection = Connect-ServiceFabricCluster -ConnectionEndpoint $config.SFConnectionEndpoint -X509Credential -FindType FindByThumbprint -FindValue $config.SFServerCertificate -ServerCertThumbprint $config.SFServerCertificate -StoreLocation LocalMachine -StoreName My if (!$connection) { $trialEndpoint = "https://$OrchestratorServerName" + ":198000" $connection = Connect-ServiceFabricCluster -ConnectionEndpoint $trialEndpoint -X509Credential -FindType FindByThumbprint -FindValue $config.SFServerCertificate -ServerCertThumbprint $config.SFServerCertificate -StoreLocation LocalMachine -StoreName My } $count = $count + 1 if (!$connection) { Write-PSFMessage -Message "Count of servers tried $count" -Level Verbose } } until ($connection -or ($count -eq $($Config.OrchestratorServerNames).Count)) if (($count -eq $($Config.OrchestratorServerNames).Count) -and (!$connection)) { Stop-PSFFunction -Message "Error: Can't connect to Service Fabric" } } $TotalApplications = (Get-ServiceFabricApplication).Count $HealthyApps = (Get-ServiceFabricApplication | Where-Object { $_.HealthState -eq "OK" }).Count if (!$EnvironmentName) { $LCSEnvironmentName = $Config.LCSEnvironmentName } else { $LCSEnvironmentName = $EnvironmentName } if (!$EnvironmentURL) { $EnvironmentURL = $Config.ClientURL } if (!$MSTeamsBuildName) { $MSTeamsBuildName = $Config.CustomModuleVersion } $Health = Get-D365LBDEnvironmentHealth -Config $config if ($StatusReportIgnorePermissionErrors) { $Health = $Health | Where-Object { $_.Details -notlike "*Check Permissions" } } if ($Health.State -contains "Down") { foreach ($issue in $($health | Where-Object { $_.State -eq 'Down' })) { $HealthCheck = "$HealthCheck" + "Down" + "$($issue.ExtraInfo)" } } else { $HealthCheck = "Operational" } $Dependency = Get-D365LBDDependencyHealth -config $Config if ($Dependency.State -contains "Down") { foreach ($issue in $($Dependency | Where-Object { $_.State -eq 'Down' })) { $DependencyCheck = "$DependencyCheck" + "Down" + " $($issue.ExtraInfo)" } } else { $DependencyCheck = "Operational" } $bodyjson = @" { "@type": "MessageCard", "@context": "http://schema.org/extensions", "themeColor": "ff0000", "title": "$LCSEnvironmentName $status", "summary": "$LCSEnvironmentName $status", "sections": [{ "facts": [{ "name": "Environment", "value": "[$LCSEnvironmentName]($EnvironmentURL)" },{ "name": "Build Version", "value": "$MSTeamsBuildName" },{ "name": "Healthy Apps/Total Apps", "value": "$HealthyApps / $TotalApplications" },{ "name": "D365 Health Check", "value": "$HealthCheck" },{ "name": "D365 Dependency Check", "value": "$DependencyCheck" }], "markdown": true }] } "@ } if ($MSTeamsExtraDetails) { Write-PSFMessage -Level VeryVerbose -Message "Adding extra Details to JSON" if ($MSTeamsExtraDetailsURI) { $Additionaljson = @" ,{ "name": "$MSTeamsExtraDetailsTitle", "value": "[$MSTeamsExtraDetails]($MSTeamsExtraDetailsURI)" }], "@ $bodyjson = $bodyjson.Replace('],', "$Additionaljson") } else { $Additionaljson = @" ,{ "name": "$MSTeamsExtraDetailsTitle", "value": "$MSTeamsExtraDetails" }], "@ $bodyjson = $bodyjson.Replace('],', "$Additionaljson") } } if (!$bodyjson) { Write-PSFMessage -Message "ERROR: JSON is empty!" -Level VeryVerbose } if ($MSTeamsURIS) { foreach ($MSTeamsURI in $MSTeamsURIS) { Write-PSFMessage -Message "Calling $MSTeamsURI with Post of $bodyjson" -Level VeryVerbose $WebRequestResults = Invoke-WebRequest -uri $MSTeamsURI -ContentType 'application/json' -Body $bodyjson -UseBasicParsing -Method Post -Verbose Write-PSFMessage -Message "$WebRequestResults" -Level VeryVerbose } } } END { } } |