functions/Set-D365LBDOptions.ps1
function Set-D365LBDOptions { <# .SYNOPSIS Uses switches to set different deployment options created for expanding the pre and post deployment scripts. .DESCRIPTION Uses switches to set different deployment options created for expanding the pre and post deployment scripts. Recommend: Run multiple times for each task then the last run run with the teams communication. .EXAMPLE $config = Get-D365Config Set-D365LBDOptions -RemoveMR -predeployment -config $config Prevents the installation of Management reporter in the predeployment stage .EXAMPLE $config = Get-D365Config Set-D365LBDOptions -predeployment -enableuserid 'stefan' -config $config Enables user stefan in the predeployment stage .EXAMPLE $config = Get-D365Config Set-D365LBDOptions -predeployment -OtherTaskName 'TalkedToMyself' -OtherTaskStatus 'Success' -config $config Adds a custom task and status to the predeployment list for communication .EXAMPLE $config = Get-D365Config Set-D365LBDOptions -postdeployment -MSTEAMSCustomStatus 'Deployment Finished' -MSTeamsURI 'https://fake.outlook.com/webhook/fakeurl/123123' -MSTeamsBuildName '2021.03.04.01' -MSTeamsExtraDetails 'Web Search' -MSTeamsExtraDetailsURI 'https://google.com' -config $config Custom status of deployment finished and added an extra field called Web Search with a link to google. Also says the Build name as '2021.03.04.01' (recommend making a build name related to the config) #> [alias("Set-D365Options")] [CmdletBinding()] param ( [PSFComputer]$ComputerName = "$env:COMPUTERNAME", [Parameter(ParameterSetName = 'Config', ValueFromPipeline = $True)] [psobject]$Config, [switch]$PreDeployment, [switch]$PostDeployment, [switch]$RemoveMR, [switch]$MaintenanceModeOn, [switch]$MaintenanceModeOff, [string]$MSTeamsURI, [string]$MSTeamsExtraDetailsURI, [string]$MSTeamsExtraDetails, [string]$MSTeamsBuildName, [string]$MSTeamsCustomStatus, [string]$SQLQueryToRun, [string]$EnableUserid, [string]$DisableUserid, [string]$OtherTaskName, [string]$OtherTaskStatus ) BEGIN { } PROCESS { if (!$Config) { $Config = Get-D365LBDConfig -ComputerName $ComputerName -HighLevelOnly } if ($PreDeployment) { Write-PSFMessage -Level Verbose -Message "PreDeployment Selected" $filenameprename = "PREDeployment" } if ($PostDeployment) { Write-PSFMessage -Level Verbose -Message "PostDeployment Selected" $filenameprename = "PostDeployment" } if ($Config) { $agentsharelocation = $Config.AgentShareLocation $AXDatabaseServer = $Config.AXDatabaseServer $AXDatabaseName = $Config.AXDatabaseName $LCSEnvironmentName = $Config.LCSEnvironmentName $clienturl = $Config.clienturl $LastRunbookTaskId = $Config.LastRunbookTaskId } if ((Test-Path $agentsharelocation\scripts\D365FOLBDAdmin) -eq $false) { new-item -path "$agentsharelocation\scripts\" -Name "D365FOLBDAdmin" -ItemType "directory" } if ($null -eq $LastRunbookTaskId) { $norunbooktaskid = get-date -Format MMddyy if ((Test-Path $agentsharelocation\scripts\D365FOLBDAdmin\$filenameprename$norunbooktaskid.xml) -eq $false) { #$newfile = New-Item $agentsharelocation -path $agentsharelocation\scripts\D365FOLBDAdmin -Name "$filenameprename$norunbooktaskid.xml" @{} | Export-Clixml "$agentsharelocation\scripts\D365FOLBDAdmin\$filenameprename$norunbooktaskid.xml" } else { Write-PSFMessage -Level VeryVerbose -Message "$filenameprename$LastRunbookTaskId.xml already exists" } } else { if ((Test-Path $agentsharelocation\scripts\D365FOLBDAdmin\$filenameprename$LastRunbookTaskId.xml) -eq $false) { $newfile = New-Item -path $agentsharelocation\scripts\D365FOLBDAdmin -Name "$filenameprename$LastRunbookTaskId.xml" @{} | Export-Clixml "$agentsharelocation\scripts\D365FOLBDAdmin\$filenameprename$LastRunbookTaskId.xml" $CLIXML = Import-Clixml "$agentsharelocation\scripts\D365FOLBDAdmin\$filenameprename$LastRunbookTaskId.xml" } else { Write-PSFMessage -Level VeryVerbose -Message "$agentsharelocation\scripts\D365FOLBDAdmin\$filenameprename$LastRunbookTaskId.xml already exists" $newfile = Get-ChildItem $agentsharelocation\scripts\D365FOLBDAdmin\$filenameprename$LastRunbookTaskId.xml $CLIXML = Import-Clixml "$agentsharelocation\scripts\D365FOLBDAdmin\$filenameprename$LastRunbookTaskId.xml" } } if ($OtherTaskName){ if (!$OtherTaskStatus){ $OtherTaskStatus = "Success" } $CLIXML += @{"$OtherTaskName" = "$OtherTaskStatus" } } if ($RemoveMR) { Write-PSFMessage -Level Verbose -Message "Attempting to Remove MR" if ($PreDeployment -eq $True) { $JsonLocation = Get-ChildItem $AgentShareLocation\wp\*\StandaloneSetup-*\SetupModules.json | Sort-Object { $_.CreationTime } -Descending | Select-Object -First 1 $JsonLocationRoot = Get-ChildItem $AgentShareLocation\wp\*\StandaloneSetup-*\ copy-item $JsonLocation.fullName -Destination $AgentShareLocation\OriginalSetupModules.json $json = Get-Content $JsonLocation.FullName -Raw | ConvertFrom-Json $json.components = $json.components | Where-Object { $_.name -ne 'financialreporting' } $json | ConvertTo-Json -Depth 100 | Out-File $JsonLocationRoot\Setupmodules.json -Force -Verbose $CLIXML += @{'Removed MR' = 'Success' } } else { Write-PSFMessage -Message "Error: Can't remove MR during anything other than PreDeployment" -Level VeryVerbose $CLIXML += @{'Removed MR' = 'Failed - Cant run outside of predeployment' } } } function Invoke-SQL { param( [string] $dataSource = ".\SQLEXPRESS", [string] $database = "MasterData", [string] $sqlCommand = $(throw "Please specify a query.") ) $connectionString = "Data Source=$dataSource; " + "Integrated Security=SSPI; " + "Initial Catalog=$database" $connection = new-object system.data.SqlClient.SQLConnection($connectionString) $command = new-object system.data.sqlclient.sqlcommand($sqlCommand, $connection) $connection.Open() $adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command $dataset = New-Object System.Data.DataSet $adapter.Fill($dataSet) | Out-Null $connection.Close() $dataSet.Tables } if ($MaintenanceModeOn) { Write-PSFMessage -Message "Turning On Maintenance Mode" -Level Verbose $SQLQuery = "update SQLSYSTEMVARIABLES SET VALUE = 1 Where PARM = 'CONFIGURATIONMODE'" $Sqlresults = invoke-sql -datasource $AXDatabaseServer -database $AXDatabaseName -sqlcommand $SQLQuery if (!$PostDeployment -or !$PreDeployment) { foreach ($AXSFServer in $config.AXSFServerNames) { Restart-Computer -ComputerName $AXSFServer -Force } } Write-PSFMessage -Message "$SQLresults" -Level VeryVerbose if ($Sqlresults) { $CLIXML += @{'Turned On Maintenance Mode' = "Success - $SQLQuery" } } else { $CLIXML += @{'Turned Off Maintenance Mode' = "Success - $SQLQuery" } } } if ($MaintenanceModeOff) { Write-PSFMessage -Message "Turning Off Maintenance Mode" -Level Verbose $SQLQuery = "update SQLSYSTEMVARIABLES SET VALUE = 0 Where PARM = 'CONFIGURATIONMODE'" $Sqlresults = invoke-sql -datasource $AXDatabaseServer -database $AXDatabaseName -sqlcommand $SQLQuery if ($PostDeployment -eq $false -or $PreDeployment -eq $false) { foreach ($AXSFServer in $config.AXSFServerNames) { Restart-Computer -ComputerName $AXSFServer -Force } } Write-PSFMessage -Message "$SQLresults" -Level VeryVerbose if ($Sqlresults) { $CLIXML += @{'Turned Off Maintenance Mode' = "Success - $SQLQuery" } } else { $CLIXML += @{'Turned Off Maintenance Mode' = "Failed - $SQLQuery" } } } if ($EnableUserid) { ##Trim 8 characters $EnableUserid = $EnableUserid.SubString(0, 8) Write-PSFMessage -Message "Enabling $EnableUserid. Note: User must already exist in system" -Level Verbose $SQLQuery = "update userinfo SET Enable = 1 Where id = '$EnableUserid'" $SQLQuery2 = "select * from userinfo where enable = 1 and id = '$EnableUserid'" $SqlresultsUpdate = invoke-sql -datasource $AXDatabaseServer -database $AXDatabaseName -sqlcommand $SQLQuery $Sqlresults = invoke-sql -datasource $AXDatabaseServer -database $AXDatabaseName -sqlcommand $SQLQuery2 if ($Sqlresults) { $CLIXML += @{"Enable User $EnableUserid" = "Success - $SQLQuery" } } else { $CLIXML += @{"Enable User $EnableUserid" = "Failed - $SQLQuery" } } Write-PSFMessage -Message "$SQLresults" -Level VeryVerbose } if ($DisableUserid) { $DisableUserid = $DisableUserid.SubString(0, 8) Write-PSFMessage -Message "Disabling $DisableUserid. Note: User must already exist in system" -Level Verbose $SQLQuery = "update userinfo SET Enable = 0 Where id = '$DisableUserid'" $SQLQuery2 = "select * from userinfo where enable = 0 and id = '$EnableUserid'" $SqlresultsUpdate = invoke-sql -datasource $AXDatabaseServer -database $AXDatabaseName -sqlcommand $SQLQuery $Sqlresults = invoke-sql -datasource $AXDatabaseServer -database $AXDatabaseName -sqlcommand $SQLQuery Write-PSFMessage -Message "$SQLresults" -Level VeryVerbose if ($Sqlresults) { $CLIXML += @{'Disable User' = "Success - $SQLQuery" } } else { $CLIXML += @{'Disable User' = "Failed - $SQLQuery" } } } if ($SQLQueryToRun) { $Sqlresults = invoke-sql -datasource $AXDatabaseServer -database $AXDatabaseName -sqlcommand $SQLQueryToRun Write-PSFMessage -Message "$SQLresults" -Level VeryVerbose $CountofSQLScripts = $($CLIXML.GetEnumerator() | Where-Object { $_.Name -like "SQL*" }).Count $CountOfSQLScripts = $CountofSQLScripts + 1 if ($Sqlresults) { $CLIXML += @{"SQL$CountOfSQLScripts" = "Success - $SQLQueryToRun" } } else { $CLIXML += @{"SQL$CountOfSQLScripts" = "Failed - $SQLQueryToRun" } } } ##EXPORT FILE AFTER CHANGES $CLIXML | Export-Clixml $newfile.FullName if ($MSTeamsURI) { Write-PSFMessage -Level VeryVerbose -Message "MSTeamsURI defined sending message" $MSTeamsFormmatedJSONofCLIItems = "" foreach ($XMLItem in $CLIXML.GetEnumerator()) { $WorkingJSON = @" ,{ "name": "$($XMLItem.Name)", "value": "$($XMLItem.Value)" } "@ $MSTeamsFormmatedJSONofCLIItems += $WorkingJSON } if ($PreDeployment) { $status = 'PreDeployment Started' } if ($PostDeployment) { $status = 'Deployment Finished. PostDeployment Started' } if ($MSTeamsCustomStatus) { $status = "$MSTeamsCustomStatus" } if ($MSTeamsFormmatedJSONofCLIItems) { $bodyjson = @" { "@type": "MessageCard", "@context": "http://schema.org/extensions", "themeColor": "ff0000", "title": "D365 $LCSEnvironmentName $status", "summary": "D365 $LCSEnvironmentName $status", "sections": [{ "facts": [{ "name": "Environment", "value": "[$LCSEnvironmentName]($clienturl)" },{ "name": "Build Version/Name", "value": "$MSTeamsBuildName" },{ "name": "Status", "value": "$status" }$MSTeamsFormmatedJSONofCLIItems], "markdown": true }] } "@ } else { $bodyjson = @" { "@type": "MessageCard", "@context": "http://schema.org/extensions", "themeColor": "ff0000", "title": "D365 $LCSEnvironmentName $status", "summary": "D365 $LCSEnvironmentName $status", "sections": [{ "facts": [{ "name": "Environment", "value": "[$LCSEnvironmentName]($clienturl)" },{ "name": "Build Version/Name", "value": "$MSTeamsBuildName" },{ "name": "Status", "value": "$status" }], "markdown": true }] } "@ } if ($MSTeamsExtraDetails) { if ($MSTeamsFormmatedJSONofCLIItems) { $bodyjson = @" { "@type": "MessageCard", "@context": "http://schema.org/extensions", "themeColor": "ff0000", "title": "D365 $LCSEnvironmentName $status", "summary": "D365 $LCSEnvironmentName $status", "sections": [{ "facts": [{ "name": "Environment", "value": "[$LCSEnvironmentName]($clienturl)" },{ "name": "Build Version", "value": "$MSTeamsBuildName" },{ "name": "Details", "value": "[$MSTeamsExtraDetails]($MSTeamsExtraDetailsURI)" },{ "name": "Status", "value": "$status" }$MSTeamsFormmatedJSONofCLIItems], "markdown": true }] } "@ } else { $bodyjson = @" { "@type": "MessageCard", "@context": "http://schema.org/extensions", "themeColor": "ff0000", "title": "D365 $LCSEnvironmentName $status", "summary": "D365 $LCSEnvironmentName $status", "sections": [{ "facts": [{ "name": "Environment", "value": "[$LCSEnvironmentName]($clienturl)" },{ "name": "Build Version", "value": "$MSTeamsBuildName" },{ "name": "Details", "value": "[$MSTeamsExtraDetails]($MSTeamsExtraDetailsURI)" },{ "name": "Status", "value": "$status" }], "markdown": true }] } "@ } } 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 { } } |