PowerShell.BTDF.psm1
#Requires -RunAsAdministrator #Requires -PSEdition Desktop if (-not [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.BizTalk.ExplorerOM")) { throw [System.ApplicationException]::new("Failed to load Microsoft.BizTalk.ExplorerOM") } if (-not [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.BizTalk.Operations")) { throw [System.ApplicationException]::new("Failed to load Microsoft.BizTalk.Operations") } if (-not [System.Reflection.Assembly]::LoadWithPartialName("SSOSettingsFileReader")) { throw [System.ApplicationException]::new("Failed to load SSOSettingsFileReader") } #region Variables $btdfTargets = @{ "BounceBizTalk" = @{ "Message" = "Boucing BizTalk" "Target" = "BounceBizTalk" } "Deploy" = @{ "Message" = "Deploying application" "Target" = "Deploy" } "DeployBAM" = @{ "Message" = "Deploying BAM" "Target" = "GetSoftwarePaths;InitializeAppName;DeployBAM" } "DeployBRE" = @{ "Message" = "Deploying BRE" "Target" = "DeployVocabAndRules" } "DeploySSO" = @{ "Message" = "Deploying SSO" "Target" = "DeploySSO" } "ImportBindings" = @{ "Message" = "Importing bindings" "Target" = "ImportBindings" } "Installer" = @{ "Message" = "Packaging" "Target" = "Installer" } "PreProcessBindings" = @{ "Message" = "Pre-Processing bindings" "Target" = "PreprocessBindings" } "QuickDeploy" = @{ "Message" = "Quick deploying application" "Target" = "UpdateOrchestration" } "Undeploy" = @{ "Message" = "Undeploying application" "Target" = "Undeploy" } "UndeployBAM" = @{ "Message" = "Undeploying BAM" "Target" = "GetSoftwarePaths;InitializeAppName;UndeployBAM" } "UndeployBRE" = @{ "Message" = "Undeploying BRE" "Target" = "UndeployVocabAndRules" } } #endregion #region BTDF <# .SYNOPSIS Helper function to clean BizTalk environment using BTDF .DESCRIPTION Uses BizTalk ExplorerOM to build a list of BizTalk applications currently installed. Each application is undeployed using "Deploy-BTDFApplication" to cleanly undeploy applications as well as handling dependencies. An exemption list is also included to leave specified, base applications .EXAMPLE PS C:\> Clean-BTDFEnvironment Removes all BTDF BizTalk applications using the Debug configuration, the default for local development .EXAMPLE PS C:\> Clean-BTDFEnvironment -Configuration Release Removes all BTDF BizTalk applications using the Release configuration .EXAMPLE PS C:\> Clean-BTDFEnvironment -Exemptions Common Removes all BTDF BizTalk applications using the Debug configuration except for the "Common" application .PARAMETER Configuration Deploys the BizTalk artifacts from the specified bin location. Debug and Release are default build configuration in VS. Server is used to (un)deploy BizTalk artifacts from an MSI installation .PARAMETER TerminateInstances Terminates BizTalk service instances as part of the undeployment process .PARAMETER Exemptions A dynamic list of applications which can be exempt from the cleaning process .NOTES General notes #> function Clean-BTDFEnvironment { [CmdletBinding()] Param ( [Parameter(HelpMessage = "Valid parameters are Debug, Release and Server. Defaults to Debug")] [ValidateSet("Debug", "Release", "Server")] [string]$Configuration = "Debug", [Parameter(HelpMessage = "Terminate instances related to deployed app")] [switch]$TerminateInstances ) DynamicParam { $btsCatalog.Refresh() $btsApps = $btsCatalog.Applications | Select-Object -Property Name, $projectPathColumn | Where-Object { $_.ProjectPath } $paramDict = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() #region DeployBTMgmtDB if ($Configuration -eq "Server") { $attributeCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]::new() $parameter = [System.Management.Automation.ParameterAttribute]::new() $parameter.HelpMessage = "Register artifacts in BizTalk DB" $attributeCollection.Add($parameter) $deployBTMgmtDBParameter = [System.Management.Automation.RuntimeDefinedParameter]::new("DeployBTMgmtDB", [switch], $attributeCollection) $paramDict.Add("DeployBTMgmtDB", $deployBTMgmtDBParameter) } #endregion #region Exemptions $attributeCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]::new() $parameter = [System.Management.Automation.ParameterAttribute]::new() $attributeCollection.Add($parameter) $validateSet = [System.Management.Automation.ValidateSetAttribute]::new([string[]]($btsApps | Select-Object -ExpandProperty Name)) $attributeCollection.Add($validateSet) $exemptionsParameter = [System.Management.Automation.RuntimeDefinedParameter]::new("Exemptions", [System.Collections.Generic.List[string]], $attributeCollection) $exemptionsParameter.Value = @() $paramDict.Add("Exemptions", $exemptionsParameter) $PSBoundParameters["Exemptions"] = [System.Collections.Generic.List[string]]::new() #endregion return $paramDict } Process { $cleanParams = @{ } if ($PSBoundParameters.ContainsKey("DeployBTMgmtDB")) { $cleanParams["DeployBTMgmtDB"] = $PSBoundParameters["DeployBTMgmtDB"] } if ($PSBoundParameters.ContainsKey("TerminateInstances")) { $cleanParams["TerminateInstances"] = $TerminateInstances } foreach ($a in $btsApps) { Write-Debug "App: $($a.Name)" $btsCatalog.Refresh() if (-not $btsCatalog.Applications[$a.Name]) { Write-Warning "$($a.Name) already removed" } elseif ($PSBoundParameters["Exemptions"].Contains($a.Name)) { Write-Verbose "$($a.Name) exempt" } else { Write-Information "Removing $($a.Name)" Deploy-BTDFApplication -ProjectPath $a.ProjectPath ` -DeploymentType Undeploy ` -Configuration $Configuration ` @cleanParams } } } } <# .SYNOPSIS Deploys a BTDF based BizTalk application .DESCRIPTION Deploys a BTDF based BizTalk application and allows configuration to support multi-server setups (Deploying resources to secondary nodes and registering application on primary node). This also uses BizTalk types to check if an upgraded application is a dependency and will strip and restore this application recursively and in order. Supports both local (Debug/Release) deployments as well as server deployments. The parameters are validated and may need adjusting should your environments be named differently .PARAMETER ProjectPath The path which the BTDF application is stored in (Eqivalent to the installation path/targetdir). Usually one level above the deployment folder for an application .PARAMETER DeploymentType Choose whether to "Deploy", "Undeploy" or "Quick Deploy (UpdateOrchestration)" the BizTalk application (Default is "Deploy") .PARAMETER Configuration Deploys the BizTalk artifacts from the specified bin location. Debug and Release are default build configuration in VS. Server is used to (un)deploy BizTalk artifacts from an MSI installation .PARAMETER Environment Select the environment to deploy. Must match what is configured in BTDF environmentsettings spreadsheet. Defaults to Local (Only applicable to Server deployments) .PARAMETER DeployBTMgmtDB Registers application in BizTalk. Assemblies/components are GACed otherwise (Only applicable to Server deployments) .PARAMETER SkipUnDeploy Skip undeploying application prior to deployment (Only applicable to Server deployments) .PARAMETER SkipBizTalkRestart If supported by deployment project, skip restarting BizTalk Host instances post-deployment .PARAMETER SkipIISRestart If supported by deployment project, skip IISReset post-deployment .PARAMETER SkipApplicationStart If supported by deployment project, don't start application after deployment .PARAMETER TerminateInstances If supported by deployment project, terminate running/suspended instances .PARAMETER SkipRestore Skips restoring dependant applciations, if any .EXAMPLE Deploy application components/assemblies C:\PS> Deploy-BTDFApplication -ProjectPath "C:\Program Files (x86)\Scratchpad" .EXAMPLE Deploy application and register in BizTalk C:\PS> Deploy-BTDFApplication -ProjectPath "C:\Program Files (x86)\Scratchpad" -Configuration Server -DeployBTMgmtDB .EXAMPLE Deploy application and register in BizTalk with live environment settings C:\PS> Deploy-BTDFApplication -ProjectPath "C:\Program Files (x86)\Scratchpad" -Configuration Server -Environment Prod -DeployBTMgmtDB .EXAMPLE Undeploys application and removes from BizTalk C:\PS> Deploy-BTDFApplication -ProjectPath "C:\Program Files (x86)\Scratchpad" -DeploymentType Undeploy -Configuration Server -DeployBTMgmtDB .NOTES General notes #> function Deploy-BTDFApplication { [CmdletBinding(SupportsShouldProcess = $true)] [OutputType([hashtable])] Param ( [Parameter(Position = 0, Mandatory = $true, ValueFromPipeline = $true, HelpMessage = "Path to the folder of the BizTalk app")] [System.IO.DirectoryInfo[]]$ProjectPath, [Parameter(HelpMessage = "Defaults to Deploy")] [ValidateSet("BounceBizTalk", "Deploy", "DeployBAM", "DeployBRE", "DeploySSO", "ImportBindings", "Installer", "PreProcessBindings", "QuickDeploy", "Undeploy", "UndeployBAM", "UndeployBRE")] [string]$DeploymentType = "Deploy", [Parameter(HelpMessage = "Valid parameters are Debug, Release and Server. Defaults to Debug")] [ValidateSet("Debug", "Release", "Server")] [string]$Configuration = "Debug", [Parameter(HelpMessage = "Valid parameters are Local, Dev , Int, UAT and Prod. Defaults to Local")] [ValidateSet("Local", "Dev", "Int", "UAT", "Train", "Prod")] [string]$Environment = "Local", [Parameter(HelpMessage = "Register artifacts in BizTalk DB")] [switch]$DeployBTMgmtDB, [Parameter(HelpMessage = "Only deploy instead of redeploy")] [switch]$SkipUnDeploy, [Parameter(HelpMessage = "Skip starting BizTalk hosts back up post deployment")] [switch]$SkipBizTalkRestart, [Parameter(HelpMessage = "Skip IISReset post deployment")] [switch]$SkipIISRestart, [Parameter(HelpMessage = "Skipping starting BizTalk app post deployment")] [switch]$SkipApplicationStart, [Parameter(HelpMessage = "Terminate instances related to deployed app")] [switch]$TerminateInstances, [Parameter(HelpMessage = "Skip restoring dependant applications")] [switch]$SkipRestore ) Process { #region Parameter checks if ($Configuration -ne "Server") { if ($PSBoundParameters.ContainsKey("Environment")) { throw [System.ArgumentException]::new("Environment must be used with the `"Server`" configuration") } if ($PSBoundParameters.ContainsKey("DeployBTMgmtDB")) { throw [System.ArgumentException]::new("DeployBTMgmtDB must be used with the `"Server`" configuration") } if ($PSBoundParameters.ContainsKey("SkipUnDeploy")) { throw [System.ArgumentException]::new("SkipUnDeploy must be used with the `"Server`" configuration") } } #endregion foreach ($pp in $ProjectPath) { Write-Debug "ProjectPath = $pp" #region Get properties from BTDF project $btdfProject = Join-Path -Path $pp -ChildPath "Deployment\Deployment.btdfproj" $btdfProjectXml = [xml](Get-Content -Path $btdfProject) $manufacturer = $btdfProjectXml.GetElementsByTagName("Manufacturer")."#text" Write-Debug "Manufacturer = $manufacturer" $projectName = $btdfProjectXml.GetElementsByTagName("ProjectName")."#text" Write-Debug "ProjectName = $projectName" #endregion #region Get back referenced applications $btsCatalog.Refresh() $btsApp = $btsCatalog.Applications["$projectName"] Write-Verbose "Checking back references for: $projectName" try { if ((-not ($Configuration -eq "Server" -and -not $DeployBTMgmtDB)) ` -and $btsApp ` -and ($DeploymentType -in "Deploy", "UnDeploy")) { if (-not $backRefs) { Write-Verbose "Creating new back refs stack" $backRefs = [System.Collections.Generic.Stack[System.Object]]::new() } $btsApps = $btsCatalog.Applications["$projectName"].BackReferences | Select-Object -Property Name, $projectPathColumn if ($btsApps.Count -gt 0) { Write-Verbose "Back refs found" } foreach ($a in $btsApps) { $btsCatalog.Refresh() if ($btsCatalog.Applications[$a.Name]) { Write-Verbose "Removing back reference: $($a.Name)" Write-Debug "BizTalk App: $($a.Name) = $($a.ProjectPath)" $undeployParams = $PSBoundParameters $undeployParams["ProjectPath"] = $a.ProjectPath $undeployParams["DeploymentType"] = "Undeploy" try { if ($PSCmdlet.ShouldProcess($a.Name, "Removing BizTalk Application")) { Deploy-BTDFApplication @undeployParams } } finally { $backRefs.Push($a) } Write-Verbose "Removed back reference: $($a.Name)" } else { Write-Warning "$($a.Name) already removed" } } if (($backRefs.Count -gt 0) -and ($btsApps.Count -gt 0)) { Write-Debug ($backRefs.GetEnumerator() | Out-String) } } else { Write-Verbose "No back references" } $backRefsRemoved = $true } catch { Write-Error -Message "Undeploying back references failed" -ErrorAction Continue Write-Error -Message "$_" -ErrorAction Continue } #endregion #region Calculate deployment variables #Calculate required properties $deployment = (Get-ChildItem -Path $pp -Filter *Deployment)[0] Write-Debug "Deployment = $($deployment.FullName)" $resultsPath = Join-Path -Path $pp -ChildPath "DeployResults\DeployResults.txt" if ($PSCmdlet.ShouldProcess($resultsPath, "Create empty MSBuild log file")) { New-Item -Path $resultsPath -ItemType File -Force | Out-Null } Write-Debug "Results = $resultsPath" #Get/Create project registry keys $manufacturerReg = if ($softwareReg32 | Join-Path -ChildPath $manufacturer | Test-Path) { $softwareReg32 | Join-Path -ChildPath $manufacturer | Get-Item } else { New-Item -Path $softwareReg32.PSPath -Name $manufacturer Write-Verbose "Created manufacturer key: $manufacturer" } $projectReg = if ($manufacturerReg | Join-Path -ChildPath $projectName | Test-Path) { $manufacturerReg | Join-Path -ChildPath $projectName | Get-Item } else { New-Item -Path $manufacturerReg.PSPath -Name $projectName Write-Verbose "Created project key: $projectName" } #Get properties from Application BTDF registry try { $version = $projectReg.GetValue("InstalledVersion") if (-not $version) { throw } Write-Debug "Version = $version" } catch { Write-Warning "Unable to find version" } #endregion #region Run EnvironmentSettingsExporter if (($DeploymentType -eq "Deploy" -or $DeploymentType -eq "PreProcessBindings") -and ($Configuration -eq "Server")) { $envSettingsDir = $deployment | Join-Path -ChildPath "EnvironmentSettings" | Get-Item Write-Debug "Environment Settings Dir = $($envSettingsDir.FullName)" $settingsExporter = Join-Path -Path $deployment.FullName -ChildPath "Framework\DeployTools\EnvironmentSettingsExporter.exe" Write-Debug "Settings Exporter = $settingsExporter" if ($PSCmdlet.ShouldProcess($settingsExporter, "Exporting BTDF settings")) { Invoke-Process -FilePath $settingsExporter ` -ArgumentList "`"$(Join-Path -Path $envSettingsDir.FullName -ChildPath \SettingsFileGenerator.xml)`"", "`"$($envSettingsDir.FullName)`"" | Out-Null } $envSettings = Join-Path -Path $envSettingsDir -ChildPath "Exported_$Environment`Settings.xml" | Get-Item Write-Debug "Environment Settings = $($envSettings.FullName)" } #endregion #region Run MSBuild and deploy if ($backRefsRemoved) { $projectReg | New-ItemProperty -Name "Configuration" -Value $Configuration -Force | Out-Null $projectReg | New-ItemProperty -Name "LastDeploySettingsFilePath" -Value $envSettings.FullName -Force | Out-Null $projectReg | New-ItemProperty -Name "Version" -Value $version -Force | Out-Null Write-Verbose "$($btdfTargets[$DeploymentType]["Message"]): $projectName" $msbuildArgs = "/t:$($btdfTargets[$DeploymentType]["Target"])", $(if ($version) { "/p:ProductVersion=$version" }), $(if (($DeploymentType -eq "Deploy") -and ($Configuration -eq "Server")) { "/p:ENV_SETTINGS=`"$($envSettings)`"" }), $(if ($PSBoundParameters.ContainsKey("TerminateInstances")) { "/p:AutoTerminateInstances=$TerminateInstances" }), $(if ($Configuration) { "/p:Configuration=$Configuration" }), $(if ($Configuration -eq "Server") { "/p:DeployBizTalkMgmtDB=$DeployBTMgmtDB" }), $(if ($PSBoundParameters.ContainsKey("SkipBizTalkRestart")) { "/p:SkipHostInstancesRestart=$SkipBizTalkRestart" }), $(if ($PSBoundParameters.ContainsKey("SkipIISRestart")) { "/p:SkipIISReset=$SkipIISRestart" }), $(if ($PSBoundParameters.ContainsKey("SkipUnDeploy")) { "/p:SkipUndeploy=$SkipUnDeploy" }), $(if ($PSBoundParameters.ContainsKey("SkipApplicationStart")) { "/p:StartApplicationOnDeploy=$(-not $SkipApplicationStart)" "/p:StartReferencedApplicationsOnDeploy=$(-not $SkipApplicationStart)" }), "/l:FileLogger,Microsoft.Build.Engine;logfile=`"$resultsPath`"" if ($PSCmdlet.ShouldProcess($btdfProject, "Deploy BTDF packaged application")) { Invoke-MSBuild -Project $btdfProject ` -ArgumentList $msbuildArgs ` -Version 4.0 ` -Run32Bit ` -ErrorAction Stop } } #endregion #region Restore back referenced applications in reverse if ($SkipRestore -and ($backRefs.Count -gt 0)) { Write-Verbose "Skipping restore" } if (($backRefs.Count -gt 0) -and ($DeploymentType -eq "Deploy") -and (-not $SkipRestore)) { Write-Debug "Back References Count = $($backRefs.Count)" while (($backRefs.Count -gt 0) -and ($DeploymentType -eq "Deploy")) { $app = $backRefs.Pop() Write-Verbose "Restoring: $($app.Name)" $deployParams = $PSBoundParameters $deployParams["ProjectPath"] = $app.ProjectPath $deployParams["DeploymentType"] = $DeploymentType $deployParams["Configuration"] = $Configuration if ($PSCmdlet.ShouldProcess($app.Name, "Restoring BizTalk Application")) { Deploy-BTDFApplication @deployParams } } } #endregion } } } <# .SYNOPSIS Installs a BTDF packaged BizTalk application to the specified directory and deploys .DESCRIPTION Requires Admin rights locally and for BizTalk. Locally installs a BTDF packaged BizTalk application to the specified directory and deploys. Deployment can be configured to support multi-server setups (install and gac assemblies on secondary nodes and register to BizTalk on primary node). This also takes into account applications which references an application to be upgraded and will strip and redeploy these. Supports configuration of multiple environments which are validated (cmdlet will need to be modified to support additional environments) .PARAMETER MsiFile Path to the MsiFile .PARAMETER TargetDir Path for the directory to install the application. The application will be installed WITHIN the specified folder rather than autocreating a folder .PARAMETER DeploymentType Choose whether to DEPLOY and UNDEPLOY the BizTalk application (Default is DEPLOY) .PARAMETER Environment Select the environment to deploy. Must match what is configured in BTDF environmentsettings spreadsheet(Defaults to Local)(Alter validated set if needed) .PARAMETER DeployBTMgmtDB Registers application in BizTalk (Without this only the assemblies/components are GACed) .PARAMETER SkipUnDeploy Skip undeploying application prior to deployment (deploy only instead of redeploy) .PARAMETER SkipBizTalkRestart If supported by deployment project, skip restarting BizTalk Host instances post-deployment .PARAMETER SkipIISRestart If supported by deployment project, skip IISReset post-deployment .PARAMETER SkipApplicationStart If supported by deployment project, don't start application after deployment .PARAMETER TerminateInstances If supported by deployment project, terminate running/suspended instances .PARAMETER SkipRestore Skips restoring dependant applciations, if any .EXAMPLE Install application components/assemblies C:\PS> Install-BTDFApplication -MsiFile C:\Deployments\Scratchpad.msi -TargetDir "C:\Program Files (x86)\Scratchpad" .EXAMPLE Install application and register in BizTalk C:\PS> Install-BTDFApplication -MsiFile C:\Deployments\Scratchpad.msi -TargetDir "C:\Program Files (x86)\Scratchpad" -DeployBTMgmtDB .EXAMPLE Install application and register in BizTalk with live environment settings C:\PS> Install-BTDFApplication -MsiFile C:\Deployments\Scratchpad.msi -TargetDir "C:\Program Files (x86)\Scratchpad" -Environment Prod -DeployBTMgmtDB .EXAMPLE Undeploys application and removes from BizTalk C:\PS> Install-BTDFApplication -MsiFile C:\Deployments\Scratchpad.msi -TargetDir "C:\Program Files (x86)\Scratchpad" -DeploymentType UnDeploy -DeployBTMgmtDB #> function Install-BTDFApplication { [CmdletBinding(SupportsShouldProcess = $true)] Param ( [Parameter(Position = 0, Mandatory = $true, HelpMessage = "Path to existing BTDF MSI")] [ValidateScript( { Test-Path -Path $_.Fullname -PathType Leaf -Include *.msi })] [System.IO.FileInfo]$MsiFile, [Parameter(Position = 1, Mandatory = $true, HelpMessage = "Path wherein the resource files will be installed")] [System.IO.DirectoryInfo]$TargetDir, [Parameter(HelpMessage = "Valid parameters as Deploy, Undeploy, UpdateOrchestration. Defaults to Deploy")] [ValidateSet("Deploy", "UnDeploy", "UpdateOrchestration")] [string]$DeploymentType = "Deploy", [Parameter(HelpMessage = "Valid parameters are Local, Dev, Int, UAT, Train and Prod. Defaults to Local")] [ValidateSet("Local", "Dev", "Int", "UAT", "Train", "Prod")] [string]$Environment = "Local", [Parameter(HelpMessage = "Register artifacts in BizTalk DB")] [switch]$DeployBTMgmtDB, [Parameter(HelpMessage = "Only deploy instead of redeploy")] [switch]$SkipUnDeploy, [Parameter(HelpMessage = "Skip starting BizTalk hosts back up post deployment")] [switch]$SkipBizTalkRestart, [Parameter(HelpMessage = "Skip IISReset post deployment")] [switch]$SkipIISRestart, [Parameter(HelpMessage = "Skipping starting BizTalk app post deployment")] [switch]$SkipApplicationStart, [Parameter(HelpMessage = "Terminate instances related to deployed app")] [switch]$TerminateInstances, [Parameter(HelpMessage = "Skip restoring dependant applications")] [switch]$SkipRestore ) Process { $TargetDir = Install-MsiFile -MsiFile $MsiFile -TargetDir $TargetDir #region Build splat params $splatParams = @{ } if ($PSBoundParameters.ContainsKey("DeployBTMgmtDB")) { $splatParams.Add("DeployBTMgmtDB", $DeployBTMgmtDB) } if ($PSBoundParameters.ContainsKey("SkipUndeploy")) { $splatParams.Add("SkipUndeploy", $SkipUndeploy) } if ($PSBoundParameters.ContainsKey("SkipBizTalkRestart")) { $splatParams.Add("SkipBizTalkRestart", $SkipBizTalkRestart) } if ($PSBoundParameters.ContainsKey("SkipIISRestart")) { $splatParams.Add("SkipIISRestart", $SkipIISRestart) } if ($PSBoundParameters.ContainsKey("SkipApplicationStart")) { $splatParams.Add("SkipApplicationStart", $SkipApplicationStart) } if ($PSBoundParameters.ContainsKey("TerminateInstances")) { $splatParams.Add("TerminateInstances", $TerminateInstances) } if ($PSBoundParameters.ContainsKey("SkipRestore")) { $splatParams.Add("SkipRestore", $SkipRestore) } #endregion Deploy-BTDFApplication -ProjectPath $TargetDir ` -Configuration "Server" ` -DeploymentType $DeploymentType ` -Environment $Environment ` @splatParams } } #endregion #region SSO <# .SYNOPSIS Read BTDF SSO settings for deployed BizTalk applications .DESCRIPTION Makes use of BTDF SSOSettingsFileReader helper assembly to read all SSO settings for a deployed application .PARAMETER Application Name of the BTDF deployed application to read SSO settings .EXAMPLE PS C:\> Read-SSO -Application Scratchpad Returns a hashtable of SSO settings for the Scratchpad application .OUTPUTS Hashtable #> function Read-SSO { [CmdletBinding()] [OutputType([hashtable])] Param ( [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)] [string]$Application ) Process { return [SSOSettingsFileReader]::Read($Application) } } <# .SYNOPSIS Read BTDF SSO settings for deployed BizTalk applications .DESCRIPTION Makes use of BTDF SSOSettingsFileReader helper assembly to read all SSO settings for a deployed application .PARAMETER Application Name of the BTDF deployed application to read SSO settings .PARAMETER Value Name of the SSO setting to get the value of .EXAMPLE PS C:\> Read-SSO -Application Scratchpad -Value NumberSetting Returns a int typed value from SSO for the Scatchpad appliction for the setting "NumberSetting" .OUTPUTS int #> function Read-SSOInt32 { [CmdletBinding()] [OutputType([int])] Param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)] [string]$Application, [Parameter(Mandatory = $true, Position = 1)] [string]$Value ) Process { return [SSOSettingsFileReader]::ReadInt32($Application, $Value) } } <# .SYNOPSIS Read BTDF SSO settings for deployed BizTalk applications .DESCRIPTION Makes use of BTDF SSOSettingsFileReader helper assembly to read all SSO settings for a deployed application .PARAMETER Application Name of the BTDF deployed application to read SSO settings .PARAMETER Value Name of the SSO setting to get the value of .EXAMPLE PS C:\> Read-SSO -Application Scratchpad -Value StringSetting Returns a string typed value from SSO for the Scatchpad appliction for the setting "StringSetting" .OUTPUTS string #> function Read-SSOString { [CmdletBinding()] [OutputType([string])] Param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)] [string]$Application, [Parameter(Mandatory = $true, Position = 1)] [string]$Value ) Process { return [SSOSettingsFileReader]::ReadString($Application, $Value) } } <# .SYNOPSIS Write settings to BTDF SSO for deployed BizTalk applications .DESCRIPTION Makes use of BTDF SSOSettingsFileReader helper assembly to read all SSO settings for a deployed application .PARAMETER Application Name of the BTDF deployed application to read SSO settings .PARAMETER Setting Name of the setting to write to. Will create the setting if it doesn't already exist .PARAMETER Value Name of the SSO setting to get the value of .EXAMPLE PS C:\> Write-SSOSetting -Application Scratchpad -Setting StringSetting -Value StringValue Returns a string typed value from SSO for the Scatchpad appliction for the setting "StringSetting" .OUTPUTS string #> function Write-SSOSetting { [CmdletBinding()] Param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)] [string]$Application, [Parameter(Mandatory = $true, Position = 1)] [string]$Setting, [Parameter(Mandatory = $true, Position = 2)] [string]$Value ) Process { [SSOSettingsFileManager.SSOSettingsManager]::WriteSetting($Application, $Setting, $Value) } } #endregion #region Private function Connect-BTSCatalog { [CmdletBinding()] [OutputType([Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer])] Param ( [Parameter()] [string]$Server = $env:COMPUTERNAME, [Parameter()] [string]$SQLInstance, [Parameter()] [string]$ManagementDB ) Process { #Calculate BizTalk connection string $wmi = Get-WmiObject -Class MSBTS_GroupSetting -Namespace root\MicrosoftBizTalkServer -ComputerName $server -ErrorAction Stop if (-not $SQLInstance) { $SQLInstance = $wmi.MgmtDbServerName } if (-not $ManagementDB) { $ManagementDB = $wmi.MgmtDbName } $btsCatalog = [Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer]::new() $btsCatalog.ConnectionString = "SERVER=$SQLInstance;DATABASE=$ManagementDB;Integrated Security=SSPI" return $btsCatalog } } Function Install-MsiFile { [CmdletBinding()] Param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelinebyPropertyName = $true)] [ValidateScript( { Test-Path -Path $_ -PathType Leaf -Include *.msi })] [string]$MsiFile, [Parameter()] [ValidateNotNullorEmpty()] [string]$TargetDir, [Parameter()] [ValidateNotNullorEmpty()] [System.Collections.Generic.List[string]]$ArgumentList ) Process { $ArgumentList += "/i", "`"$msiFile`"", $(if ($targetDir) { "INSTALLDIR=`"$targetDir`"" }), "ADDLOCAL=ALL", "/qn", "/norestart" Write-Verbose "Installing MSI File..." $process = Invoke-Process -FilePath "$env:windir\System32\msiexec.exe" -ArgumentList $ArgumentList switch ($process.ExitCode) { 0 { Write-Verbose "MSI been successfully installed" } Default { Write-Error "Installing $MsiFile failed!, Exit Code: $($process.ExitCode)" } } return $TargetDir } } function Invoke-MSBuild { [CmdletBinding()] Param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)] [ValidateScript( { Test-Path -Path $_ -PathType Leaf -Include *.*proj })] [string]$Project, [Parameter(Position = 1)] [System.Collections.Generic.List[string]]$ArgumentList, [Parameter()] [switch]$Run32Bit # [Parameter()] # [ValidateNotNullOrEmpty()] # [ValidateScript({[version]::Parse($_)})] # [string]$Version ) DynamicParam { $msbuildReg = if ($Run32Bit -and ($env:PROCESSOR_ARCHITECTURE -eq "AMD64")) { Get-Item -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\MSBuild\ToolsVersions" } else { Get-Item -Path "HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions" } $versions = $msbuildReg | Get-ChildItem | Get-ItemProperty | Sort-Object -Property @{Expression = { [version]::Parse($_.PSChildName) } } -Descending $paramDict = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary #region Version $attributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute] $parameter = New-Object System.Management.Automation.ParameterAttribute $attributeCollection.Add($parameter) $validateSet = New-Object System.Management.Automation.ValidateSetAttribute($versions | Select-Object -ExpandProperty PSChildName) $attributeCollection.Add($validateSet) $versionParameter = New-Object System.Management.Automation.RuntimeDefinedParameter("Version", [string], $attributeCollection) $paramDict.Add("Version", $versionParameter) #endregion return $paramDict } Process { $versionsHash = @{ } $versions | ForEach-Object { $versionsHash[$($_.PSChildName)] = $_.MSBuildToolsPath } $version = if (-not $PSBoundParameters.ContainsKey("Version")) { $versions[0].PSChildName } else { $PSBoundParameters.Version } Write-Debug "Version = $version" $msbuildFolder = $versionsHash[$version] Write-Debug "MSBuildFolder = $msbuildFolder" $msbuild = Join-Path -Path $msbuildFolder -ChildPath "msbuild.exe" $ArgumentList = "`"$Project`"", $ArgumentList, "/p:UseSharedCompilation=false", "/noLogo", "/maxcpucount:1", "/nodeReuse:false" Invoke-Process -FilePath $msbuild -ArgumentList $ArgumentList | Out-Null } } function Invoke-Process { [CmdletBinding()] Param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [ValidateNotNullOrEmpty()] [ValidateScript( { Test-Path -Path $_ -PathType Leaf -Include *.* })] [System.IO.FileInfo]$FilePath, [Parameter()] [ValidateNotNullOrEmpty()] [string[]]$ArgumentList ) Process { $stdOutTempFile = "$env:TEMP\$((New-Guid).Guid)" $stdErrTempFile = "$env:TEMP\$((New-Guid).Guid)" Write-Verbose "Invoking $($FilePath.Name)" $processParams = @{ "FilePath" = $FilePath.FullName "Wait" = $true "PassThru" = $true "NoNewWindow" = $true } Write-Debug "FilePath = $($FilePath.FullName)" if ($ArgumentList) { $processParams.Add("ArgumentList", $ArgumentList) Write-Debug "ArgumentList = $ArgumentList" } #Redirect output if executed remotely if ((Get-Host).Name -eq "ServerRemoteHost") { $processParams["RedirectStandardOutput"] = $stdOutTempFile $processParams["RedirectStandardError"] = $stdErrTempFile Write-Debug "TempStdOutput = $stdOutTempFile" Write-Debug "TempStdError = $stdErrTempFile" } try { $process = Start-Process @processParams switch ($process.ExitCode) { 0 { Write-Verbose "Process has been successfully run" return $process } Default { throw "Process failed!, Exit Code: $($process.ExitCode)" } } } catch { throw $_ } finally { if ((Get-Host).Name -eq "ServerRemoteHost") { $processOutput = (Get-Content -Path $stdOutTempFile -Raw) $processError = Get-Content -Path $stdErrTempFile -Raw if ($processOutput) { Write-Information $processOutput } if ($processError) { Write-Error $processError } } Remove-Item -Path $stdOutTempFile, $stdErrTempFile ` -Force ` -Verbose:$false ` -ErrorAction Ignore ` } } } #endregion #region Variables $btsCatalog = Connect-BTSCatalog $projectPathColumn = @{Name = "ProjectPath"; Expression = { Read-SSOString -Application $_.Name -Value "ProjectPath" } } $softwareReg32 = if ($env:PROCESSOR_ARCHITECTURE -eq "AMD64") { Get-Item -Path HKLM:\SOFTWARE\Wow6432Node } else { Get-Item -Path HKLM:\SOFTWARE } #endregion |