Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Hi,
the intension of this three-part series is to get a picture of what you have to change on the xSCOM DSC Module to make it aware of SCOM 2016. I will show you what and where you have to change. Please use this as a modular example of how Powershell DSC modules can be manipulated to fit your needs. In the upcoming Part 4 I will show you how to use this xSCOM Module to deploy a complete SCOM environment.
Customize the PS DSC Modules Part 2:
Here will the development begin. You can find the modules at the following path: '$env:CommonProgramFiles\WindowsPowerShell\Modules'
We need to adjust the following DSCResources from the xScom Module:
MSFT_xSCOMConsoleSetup (described in Part 1 of this blog series) MSFT_xSCOMConsoleUpdate (described in Part 1 of this blog series)
MSFT_xSCOMManagementServerSetup (described in Part 2 of this blog series)
MSFT_xSCOMManagementServerUpdate (described in Part 2 of this blog series)
MSFT_xSCOMWebConsoleServerSetup (described in Part 3 of this blog series) MSFT_xSCOMWebConsoleServerUpdate (described in Part 3 of this blog series)
Each Module folder contains two files. We need to edit the *.PSM (Powershell Module file). Please create a backup before. Each *.PSM file consists of three major Functions:
get-targetresource (needs to be manipulated)
set-targetresource (needs to be manipulated)
test-targetresource (no changes are required)
Please edit the MSFT_xSCOMManagementServerSetup.psm1 from the MSFT_xSCOMManagementServerSetup folder and go to the first section (Get-Targetresource)
Add the following condition part to the switch statement:
"7.2.11719.0"
{
$IdentifyingNumber = "{1199B530-E226-46DC-B7F4-7891D5AFCF22}"
$InstallRegVersion = "12"
$RegVersion = "3.0"
}
And next add the following switch condition to the switch statement in the Set-Targetresource function:
"7.2.11719.0"
{
$IdentifyingNumber = "{1199B530-E226-46DC-B7F4-7891D5AFCF22}"
$InstallRegVersion = "12"
}
After that the MSFT_xSCOMManagementServerSetup.psm1 file is aware of SCOM 2016 Management Server installations and DSC can push or pull a SCOM 2016 Management Server.
Now it should look like:
function Get-TargetResource
{
[CmdletBinding()]
[OutputType([System.Collections.Hashtable])]
param
(
[parameter(Mandatory = $true)]
[ValidateSet("Present","Absent")]
[System.String]
$Ensure = "Present",
[parameter(Mandatory = $true)]
[System.String]
$SourcePath,
[System.String]
$SourceFolder = "\SystemCenter2012R2\OperationsManager.en",
[parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$SetupCredential,
[System.String]
$ProductKey,
[System.String]
$InstallPath,
[parameter(Mandatory = $true)]
[System.String]
$ManagementGroupName,
[parameter(Mandatory = $true)]
[System.Boolean]
$FirstManagementServer,
[System.UInt16]
$ManagementServicePort = 5723,
[System.Management.Automation.PSCredential]
$ActionAccount,
[System.Management.Automation.PSCredential]
$DASAccount,
[parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$DataReader,
[parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$DataWriter,
[parameter(Mandatory = $true)]
[System.String]
$SqlServerInstance,
[System.String]
$DatabaseName = "OperationsManager",
[System.UInt16]
$DatabaseSize = 1000,
[parameter(Mandatory = $true)]
[System.String]
$DwSqlServerInstance,
[System.String]
$DwDatabaseName = "OperationsManagerDW",
[System.UInt16]
$DwDatabaseSize = 1000,
[System.Byte]
$UseMicrosoftUpdate,
[System.Byte]
$SendCEIPReports,
[ValidateSet("Never","Queued","Always")]
[System.String]
$EnableErrorReporting = "Never",
[System.Byte]
$SendODRReports
)
Import-Module $PSScriptRoot\..\..\xPDT.psm1
$Path = Join-Path -Path (Join-Path -Path $SourcePath -ChildPath $SourceFolder) -ChildPath "setup.exe"
$Path = ResolvePath $Path
$Version = (Get-Item -Path $Path).VersionInfo.ProductVersion
switch($Version)
{
"7.2.11719.0"
{
$IdentifyingNumber = "{1199B530-E226-46DC-B7F4-7891D5AFCF22}"
$InstallRegVersion = "12"
$RegVersion = "3.0"
}
"7.1.10226.0"
{
$IdentifyingNumber = "{C92727BE-BD12-4140-96A6-276BA4F60AC1}"
$InstallRegVersion = "12"
$RegVersion = "3.0"
}
"7.2.10015.0"
{
$IdentifyingNumber = "{43C498CB-D391-4B07-9C03-85C4E8239102}"
$InstallRegVersion = "12"
$RegVersion = "3.0"
}
Default
{
throw "Unknown version of Operations Manager!"
}
}
if(Get-WmiObject -Class Win32_Product | Where-Object {$_.IdentifyingNumber -eq $IdentifyingNumber})
{
$InstallPath = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\System Center Operations Manager\$InstallRegVersion\Setup" -Name "InstallDirectory").InstallDirectory
$MGs = Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\Microsoft Operations Manager\$RegVersion\Server Management Groups"
foreach($MG in $MGs)
{
$MGReg = $MG.Name.Replace("HKEY_LOCAL_MACHINE\","HKLM:")
if ((Get-ItemProperty -Path $MGReg -Name "IsServer").IsServer -eq 1)
{
$ManagementGroupName = $MG.Name.Split("\")[$MG.Name.Split("\").Count - 1]
$ManagementServicePort = (Get-ItemProperty -Path $MGReg -Name "Port").Port
}
}
$ComputerName = $env:COMPUTERNAME + "." + (Get-WmiObject -Class Win32_ComputerSystem).Domain
if(!(Get-Module -Name OperationsManager))
{
Import-Module "$InstallPath\PowerShell\OperationsManager"
}
if(Get-Module -Name OperationsManager)
{
$ManagementServer = Get-SCOMManagementServer -Name $ComputerName
$ActionAccountUsername = $ManagementServer.ActionAccountIdentity
$DRA = (Get-SCOMRunAsAccount -Name "Data Warehouse Report Deployment Account")
$DataReaderUsername = $DRA.Domain + "\" + $DRA.UserName
$DWA = (Get-SCOMRunAsAccount -Name "Data Warehouse Action Account")
$DataWriterUsername = $DWA.Domain + "\" + $DWA.UserName
}
$DASAccountUsername = (Get-WmiObject -Class Win32_Service | Where-Object {$_.Name -eq "OMSDK"}).StartName
$SqlServerInstance = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft Operations Manager\$RegVersion\Setup" -Name "DatabaseServerName").DatabaseServerName
$DatabaseName = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft Operations Manager\$RegVersion\Setup" -Name "DatabaseName").DatabaseName
$DwSqlServerInstance = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft Operations Manager\$RegVersion\Setup" -Name "DataWarehouseDBServerName").DataWarehouseDBServerName
$DwDatabaseName = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft Operations Manager\$RegVersion\Setup" -Name "DataWarehouseDBName").DataWarehouseDBName
$returnValue = @{
Ensure = "Present"
SourcePath = $SourcePath
SourceFolder = $SourceFolder
InstallPath = $InstallPath
ManagementGroupName = $ManagementGroupName
ManagementServicePort = $ManagementServicePort
ActionAccountUsername = $ActionAccountUsername
DASAccountUsername = $DASAccountUsername
DataReaderUsername = $DataReaderUsername
DataWriterUsername = $DataWriterUsername
SqlServerInstance = $SqlServerInstance
DatabaseName = $DatabaseName
DwSqlServerInstance = $DwSqlServerInstance
DwDatabaseName = $DwDatabaseName
}
}
else
{
$returnValue = @{
Ensure = "Absent"
SourcePath = $SourcePath
SourceFolder = $SourceFolder
}
}
$returnValue
}
function Set-TargetResource
{
[CmdletBinding()]
param
(
[parameter(Mandatory = $true)]
[ValidateSet("Present","Absent")]
[System.String]
$Ensure = "Present",
[parameter(Mandatory = $true)]
[System.String]
$SourcePath,
[System.String]
$SourceFolder = "\SystemCenter2012R2\OperationsManager.en",
[parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$SetupCredential,
[System.String]
$ProductKey,
[System.String]
$InstallPath,
[parameter(Mandatory = $true)]
[System.String]
$ManagementGroupName,
[parameter(Mandatory = $true)]
[System.Boolean]
$FirstManagementServer,
[System.UInt16]
$ManagementServicePort = 5723,
[System.Management.Automation.PSCredential]
$ActionAccount,
[System.Management.Automation.PSCredential]
$DASAccount,
[parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$DataReader,
[parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$DataWriter,
[parameter(Mandatory = $true)]
[System.String]
$SqlServerInstance,
[System.String]
$DatabaseName = "OperationsManager",
[System.UInt16]
$DatabaseSize = 1000,
[parameter(Mandatory = $true)]
[System.String]
$DwSqlServerInstance,
[System.String]
$DwDatabaseName = "OperationsManagerDW",
[System.UInt16]
$DwDatabaseSize = 1000,
[System.Byte]
$UseMicrosoftUpdate,
[System.Byte]
$SendCEIPReports,
[ValidateSet("Never","Queued","Always")]
[System.String]
$EnableErrorReporting = "Never",
[System.Byte]
$SendODRReports
)
Import-Module $PSScriptRoot\..\..\xPDT.psm1
$Path = Join-Path -Path (Join-Path -Path $SourcePath -ChildPath $SourceFolder) -ChildPath "setup.exe"
$Path = ResolvePath $Path
$Version = (Get-Item -Path $Path).VersionInfo.ProductVersion
switch($Version)
{
"7.2.11719.0"
{
$IdentifyingNumber = "{1199B530-E226-46DC-B7F4-7891D5AFCF22}"
$InstallRegVersion = "12"
}
"7.1.10226.0"
{
$IdentifyingNumber = "{C92727BE-BD12-4140-96A6-276BA4F60AC1}"
$InstallRegVersion = "12"
}
"7.2.10015.0"
{
$IdentifyingNumber = "{43C498CB-D391-4B07-9C03-85C4E8239102}"
$InstallRegVersion = "12"
}
Default
{
throw "Unknown version of Operations Manager!"
}
}
switch($Ensure)
{
"Present"
{
# Set defaults, if they couldn't be set in param due to null configdata input
if($ManagementServicePort -eq 0)
{
$ManagementServicePort = 5723
}
if($DatabaseSize -eq 0)
{
$DatabaseSize = 1000
}
if($DwDatabaseSize -eq 0)
{
$DwDatabaseSize = 1000
}
if($UseMicrosoftUpdate -ne 1)
{
$UseMicrosoftUpdate = 0
}
if($SendCEIPReports -ne 1)
{
$SendCEIPReports = 0
}
if($SendODRReports -ne 1)
{
$SendODRReports = 0
}
# Remove default instance name
$SqlServerInstance = $SqlServerInstance.Replace("\MSSQLSERVER","")
$DwSqlServerInstance = $DwSqlServerInstance.Replace("\MSSQLSERVER","")
# Create install arguments
$Arguments = "/silent /install /AcceptEndUserLicenseAgreement:1 /components:OMServer"
$ArgumentVars = @(
"InstallPath",
"UseMicrosoftUpdate",
"SendCEIPReports",
"EnableErrorReporting",
"SendODRReports",
"ManagementServicePort",
"SqlServerInstance",
"DatabaseName"
)
if($FirstManagementServer)
{
$ArgumentVars += @(
"ManagementGroupName",
"DatabaseSize",
"DwSqlServerInstance",
"DwDatabaseName",
"DwDatabaseSize"
)
}
foreach($ArgumentVar in $ArgumentVars)
{
if(!([String]::IsNullOrEmpty((Get-Variable -Name $ArgumentVar).Value)))
{
$Arguments += " /$ArgumentVar`:" + [Environment]::ExpandEnvironmentVariables((Get-Variable -Name $ArgumentVar).Value)
}
}
$AccountVars = @("ActionAccount","DASAccount","DataReader","DataWriter")
foreach($AccountVar in $AccountVars)
{
if($PSBoundParameters.ContainsKey("ActionAccount") -or $PSBoundParameters.ContainsKey($AccountVar))
{
$Arguments += " /$AccountVar`User:" + (Get-Variable -Name $AccountVar).Value.UserName
$Arguments += " /$AccountVar`Password:" + (Get-Variable -Name $AccountVar).Value.GetNetworkCredential().Password
}
else
{
if(($AccountVar -eq "ActionAccount") -or ($AccountVar -eq "DASAccount"))
{
$Arguments += " /UseLocalSystem$AccountVar"
}
}
}
# Replace sensitive values for verbose output
$Log = $Arguments
$LogVars = @("ActionAccount","DASAccount","DataReader","DataWriter")
foreach($LogVar in $LogVars)
{
if((Get-Variable -Name $LogVar).Value -ne "")
{
$Log = $Log.Replace((Get-Variable -Name $LogVar).Value.GetNetworkCredential().Password,"********")
}
}
}
"Absent"
{
# Create uninstall arguments
$Arguments = "/silent /uninstall /components:OMServer"
$Log = $Arguments
}
}
Write-Verbose "Path: $Path"
Write-Verbose "Arguments: $Log"
$Process = StartWin32Process -Path $Path -Arguments $Arguments -Credential $SetupCredential -AsTask
Write-Verbose $Process
WaitForWin32ProcessEnd -Path $Path -Arguments $Arguments -Credential $SetupCredential
# Additional first Management Server "Present" actions
if(($Ensure -eq "Present") -and $FirstManagementServer -and (Get-WmiObject -Class Win32_Product | Where-Object {$_.IdentifyingNumber -eq $IdentifyingNumber}))
{
# Set ProductKey
if($PSBoundParameters.ContainsKey("ProductKey"))
{
Write-Verbose "Set product key"
Invoke-Command -ComputerName . -Credential $SetupCredential -Authentication Credssp -ScriptBlock {
$ProductKey = $args[0]
$InstallRegVersion = $args[1]
$InstallPath = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\System Center Operations Manager\$InstallRegVersion\Setup" -Name "InstallDirectory").InstallDirectory
Import-Module "$([Environment]::ExpandEnvironmentVariables($InstallPath))\Powershell\OperationsManager"
Set-SCOMLicense -ProductID $ProductKey -Confirm:$false
} -ArgumentList @($ProductKey,$InstallRegVersion)
Restart-Service omsdk
Restart-Service cshost
}
# Wait for Management Service
$ErrorActionPreference = "SilentlyContinue"
foreach($Port in @($ManagementServicePort,5724))
{
$MSOpen = $false
while(!$MSOpen)
{
$Socket = New-Object Net.Sockets.TcpClient
$Socket.Connect("localhost",$Port)
if($Socket.Connected)
{
$MSOpen = $true
}
else
{
Write-Verbose "Wait for Management Server port $Port to open"
Start-Sleep 60
}
$Socket = $null
}
}
$ErrorActionPreference = "Continue"
# Allow MS to initialize
Start-Sleep 300
}
if((Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Name 'PendingFileRenameOperations' -ErrorAction SilentlyContinue) -ne $null)
{
$global:DSCMachineStatus = 1
}
else
{
if(!(Test-TargetResource @PSBoundParameters))
{
throw "Set-TargetResouce failed"
}
}
}
function Test-TargetResource
{
[CmdletBinding()]
[OutputType([System.Boolean])]
param
(
[parameter(Mandatory = $true)]
[ValidateSet("Present","Absent")]
[System.String]
$Ensure = "Present",
[parameter(Mandatory = $true)]
[System.String]
$SourcePath,
[System.String]
$SourceFolder = "\SystemCenter2012R2\OperationsManager.en",
[parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$SetupCredential,
[System.String]
$ProductKey,
[System.String]
$InstallPath,
[parameter(Mandatory = $true)]
[System.String]
$ManagementGroupName,
[parameter(Mandatory = $true)]
[System.Boolean]
$FirstManagementServer,
[System.UInt16]
$ManagementServicePort = 5723,
[System.Management.Automation.PSCredential]
$ActionAccount,
[System.Management.Automation.PSCredential]
$DASAccount,
[parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$DataReader,
[parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$DataWriter,
[parameter(Mandatory = $true)]
[System.String]
$SqlServerInstance,
[System.String]
$DatabaseName = "OperationsManager",
[System.UInt16]
$DatabaseSize = 1000,
[parameter(Mandatory = $true)]
[System.String]
$DwSqlServerInstance,
[System.String]
$DwDatabaseName = "OperationsManagerDW",
[System.UInt16]
$DwDatabaseSize = 1000,
[System.Byte]
$UseMicrosoftUpdate,
[System.Byte]
$SendCEIPReports,
[ValidateSet("Never","Queued","Always")]
[System.String]
$EnableErrorReporting = "Never",
[System.Byte]
$SendODRReports
)
$result = ((Get-TargetResource @PSBoundParameters).Ensure -eq $Ensure)
$result
}
Export-ModuleMember -Function *-TargetResource
Next we add a few lines to the MSFT_xSCOMManagementServerUpdate for deploying the newest SCOM UpdateRollup (UR3 in this case)
Please edit the MSFT_xSCOMManagementServerUpdate.psm1 from the MSFT_xSCOMManagementServerUpdate folder and go to the first section (Get-Targetresource)
Find the following Where clause:
Where-Object {$_.Name -eq "System Center Operations Manager 2012 Server"}).Version
And change it to:
Where-Object {$_.Name -eq "System Center Operations Manager 2016 Server"}).Version
And next add the following switch condition to the switch statement in the Get-Targetresource function:
"7.2.11719.0"
{
$ProductCode = "{1199B530-E226-46DC-B7F4-7891D5AFCF22}"
$PatchID = "{997B7B7E-01A2-460C-9F48-3F0BF3FE8622}"
$Update = "Update Rollup 3"
}
And now add the following lines to the switch statement in the Set-Targetresource function:
"7.2.11719.0"
{
$UpdateFile = "KB4016126-AMD64-Server.msp"
}
After that the MSFT_xSCOMManagementServerUpdate file is aware of SCOM 2016 UR3 Management Server updates and DSC can push or pull a SCOM 2016 Management Server UpdateRollup 3.
Now it should look like:
function Get-TargetResource
{
[CmdletBinding()]
[OutputType([System.Collections.Hashtable])]
param
(
[parameter(Mandatory = $true)]
[ValidateSet("Present","Absent")]
[System.String]
$Ensure = "Present",
[parameter(Mandatory = $true)]
[System.String]
$SourcePath,
[System.String]
$SourceFolder = "\TEMP\Operationsmanager\Updates",
[parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$SetupCredential
)
$Version = (Get-WmiObject -Class Win32_Product | Where-Object {$_.Name -eq "System Center Operations Manager 2016 Server"}).Version
switch($Version)
{
"7.2.11719.0"
{
$ProductCode = "{1199B530-E226-46DC-B7F4-7891D5AFCF22}"
$PatchID = "{997B7B7E-01A2-460C-9F48-3F0BF3FE8622}"
$Update = "Update Rollup 3"
}
"7.1.10226.0"
{
$ProductCode = "{C92727BE-BD12-4140-96A6-276BA4F60AC1}"
$PatchID = "{F6930A3E-016D-4F88-9186-440090A836DF}"
$Update = "Update Rollup 4"
}
"7.2.10015.0"
{
$returnValue = @{
Ensure = "Present"
SourcePath = $SourcePath
SourceFolder = $SourceFolder
Update = "None"
}
}
$null
{
$returnValue = @{
Ensure = "Absent"
SourcePath = $SourcePath
SourceFolder = $SourceFolder
}
}
Default
{
throw "Unknown version of Operations Manager!"
}
}
if($ProductCode -and $PatchID -and (Get-WmiObject -Class Win32_PatchPackage | Where-Object {($_.ProductCode -eq $ProductCode) -and ($_.PatchID -eq $PatchID)}))
{
$returnValue = @{
Ensure = "Present"
SourcePath = $SourcePath
SourceFolder = $SourceFolder
Update = $Update
}
}
else
{
$returnValue = @{
Ensure = "Absent"
SourcePath = $SourcePath
SourceFolder = $SourceFolder
}
}
$returnValue
}
function Set-TargetResource
{
[CmdletBinding()]
param
(
[parameter(Mandatory = $true)]
[ValidateSet("Present","Absent")]
[System.String]
$Ensure = "Present",
[parameter(Mandatory = $true)]
[System.String]
$SourcePath,
[System.String]
$SourceFolder = "\TEMP\Operationsmanager\Updates",
[parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$SetupCredential
)
$Version = (Get-WmiObject -Class Win32_Product | Where-Object {$_.Name -eq "System Center Operations Manager 2016 Server"}).Version
switch($Version)
{
"7.2.11719.0"
{
$UpdateFile = "KB4016126-AMD64-Server.msp"
}
"7.1.10226.0"
{
$UpdateFile = "KB2992020-AMD64-Server.msp"
}
"7.2.10015.0"
{
Write-Verbose "No update for this version of Operations Manager!"
}
$null
{
Write-Verbose "Operations Manager Management Server not installed!"
}
Default
{
throw "Unknown version of Operations Manager!"
}
}
if($UpdateFile)
{
Import-Module $PSScriptRoot\..\..\xPDT.psm1
$Path = "msiexec.exe"
$Path = ResolvePath $Path
Write-Verbose "Path: $Path"
$MSPPath = Join-Path -Path (Join-Path -Path $SourcePath -ChildPath $SourceFolder) -ChildPath $UpdateFile
$MSPPath = ResolvePath $MSPPath
$Arguments = "/update $MSPPath /norestart"
Write-Verbose "Arguments: $Arguments"
$Process = StartWin32Process -Path $Path -Arguments $Arguments -Credential $SetupCredential
Write-Verbose $Process
WaitForWin32ProcessEnd -Path $Path -Arguments $Arguments -Credential $SetupCredential
}
if((Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Name 'PendingFileRenameOperations' -ErrorAction SilentlyContinue) -ne $null)
{
$global:DSCMachineStatus = 1
}
else
{
if(!(Test-TargetResource @PSBoundParameters))
{
throw "Set-TargetResouce failed"
}
}
}
function Test-TargetResource
{
[CmdletBinding()]
[OutputType([System.Boolean])]
param
(
[parameter(Mandatory = $true)]
[ValidateSet("Present","Absent")]
[System.String]
$Ensure = "Present",
[parameter(Mandatory = $true)]
[System.String]
$SourcePath,
[System.String]
$SourceFolder = "\SystemCenter2012R2\OperationsManager.en\Updates",
[parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$SetupCredential
)
$result = ((Get-TargetResource @PSBoundParameters).Ensure -eq $Ensure)
$result
}
Export-ModuleMember -Function *-TargetResource
Comments
- Anonymous
December 17, 2017
The comment has been removed