We have moved our system alerting over to SCOM 2012 and receive heartbeat alerts when servers go offline. Presently there are approximately 750 servers in the vDC that I am managing. The SCOM 2012 server is in a different untrusted domain.
I have one working script where it puts the servers in Maintenance mode, but its run serially and takes about 40 minutes to put nearly 400 servers in Maintenance Mode. This is a workable solution, but I would like to use the foreach -parallel command to speed it up.
I have my workflow (to use the foreach -parallel command) created and placed in one of the default PowerShell Module locations on the Source and Destination Machines. I've tested the set of commands outside of the workflow on the SCOM server and it runs successfully. When I try to run the command remotely via an Invoke-command, the SCOM commands come back as being unrecognized.
#Get Date for usage in Connection Name
$Date = Get-Date -Format HHmmsss
#combine Name with Date to uniquify
$name = "ScomMM" + $Date
#Collect Servers from WSUS Server
[reflection.assembly]::LoadWithPartialName("Microsoft.Updateservices.Administration") | out-null
$WSUS = [Microsoft.updateservices.administration.adminproxy]::Getupdateserver("ServerName",$false,8530);
$TS = $wsus.getcomputertargetgroups() | ? {($_.name -eq "Group1") -or ($_.Name -eq "Group2")}
$computers = $TS.getcomputertargets() | Select-Object FullDomainName
#Setup Trusted host
invoke-Command -ScriptBlock {(winrm.cmd s winrm/config/client '@{TrustedHosts="*PublicIPAddress*"}')}
Enable-PSRemoting -Force
#Credentials stored in a file
$username = "username"
$password = get-content 'Path' | convertto-securestring
$creds = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $username,$password
$session = new-PSSession -ComputerName "IPAddress" -Credential $creds -Name $name
#SCOM Commands Module
Import-Module OperationsManager
#Workflow
Import-Module Set-MM
#Run the command remotely
Invoke-Command -Session $session -ScriptBlock {
Import-Module -Name Set-MM
Set-MM -computers $using:computers
}
#Workflow - Stored at C:\Windows\System32\WindowsPowerShell\v1.0\Modules\Set-MM\Set-MM.psm1
Workflow Set-MM
{
Param($computers)
Foreach -Parallel($computer in $computers)
{
Get-SCOMClassInstance -Name $computers.FullDomainName | Start-SCOMMaintenanceMode -EndTime (Get-Date).AddMinutes(6) -Reason PlannedOperatingSystemReconfiguration
}
}
At C:\Windows\system32\WindowsPowerShell\v1.0\Modules\Set-MM\Set-MM.psm1:6 char:3
+ Get-SCOMClassInstance -Name $computers.FullDomainName | Start ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Cannot find the 'Get-SCOMClassInstance' command. If this command is defined as a workflow, ensure it is
defined before the workflow that calls it. If it is a command intended to run directly within Windows
PowerShell (or is not available on this system), place it in an InlineScript: 'InlineScript {
Get-SCOMClassInstance }'
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : CommandNotFound
+ PSComputerName : IPAddress
The term 'Set-MM' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
+ CategoryInfo : ObjectNotFound: (Set-MM:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
+ PSComputerName : IPAddress
Get-PSSession | Remove-PSSession
If I use an Inlinescript on the script inside the foreach -Parallel
InlineScript{Get-SCOMClassInstance -Name $Using:computers.FullDomainName | Start-SCOMMaintenanceMode -EndTime (Get-Date).AddMinutes(6) -Reason PlannedOperatingSystemReconfiguration}
I get this for each computer that is attempting to get processed in the workflow:
The term 'Get-SCOMClassInstance' is not recognized as the name of a cmdlet, function, script file, or
operable program. Check the spelling of the name, or if a path was included, verify that the path is
correct and try again.
+ CategoryInfo : ObjectNotFound: (Get-SCOMClassInstance:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
+ PSComputerName : ServerName