Monthly Archives: December 2016

How do I: Create a task that will allow me to bulk adjust a regkey via the SCOM Console

There are lots of ways to adjust reg keys in bulk. SCCM, Group Policy, Remote PowerShell to name a few.

Occasionally I find that SCOM customers like to have the ability to modify a registry setting via a Task in the SCOM console. This gives them the ability to modify the regkey for a single server, a group of servers, all servers, whatever they want in a matter of seconds without having to rely on outside tools.

Recently I have had a few customers need to adjust the MaxQueueSize reg key for their agents:

This is actually a fairly good simple MP Authoring exercise so I will quick walkthrough the process.

The end design in Visual Studio will look like this:

regkeymp

Easy enough, two Tasks, and two Scripts, standard out-of-box references – which then generate two tasks in the console:

task

Usually for something like this I like to start with the PowerShell before I break open Visual Studio. It is easier for me to get the script working in the PowerShell ISE and then start a new MP once I know I have the PowerShell working.

For the most part the PowerShell is pretty straight forward. The only complication I ran into in testing was that  since some of my customer’s agents are multi-homed and some aren’t I needed a way to handle either scenario without erroring out. Handling multiple management groups adds three lines of code to my original script, but still not too bad:

$GetParentKey = Get-Item -Path ‘HKLM:\SYSTEM\CurrentControlSet\services\HealthService\Parameters\Management Groups’
$MGName = $GetParentKey.getsubkeynames()
Foreach ($Name in $MGName)
{
Set-ItemProperty -Path “HKLM:\SYSTEM\CurrentControlSet\services\HealthService\Parameters\Management Groups\$Name” -Name ‘maximumQueueSizeKb’ -Value 76800 -Force
}


To make things as simple as possible in this example I am using hardcoded QueueSize Values. One Task to increase the queue size to 75 MB, and one to set it back to the default of 15 MB.

$GetParentKey = Get-Item -Path ‘HKLM:\SYSTEM\CurrentControlSet\services\HealthService\Parameters\Management Groups’
$MGName = $GetParentKey.getsubkeynames()
Foreach($Name in $MGName){
Set-ItemProperty-Path “HKLM:\SYSTEM\CurrentControlSet\services\HealthService\Parameters\Management Groups\$Name” -Name ‘maximumQueueSizeKb’ -Value 15360 -Force
}

Now that we have the scripts we can open up our copy of Visual Studio with the Visual Studio Authoring Extensions:

File – New Project

newproj

Management Pack – Operations Manager 2012 R2

opsproj

create

We are going to create two folders. These aren’t required, I just like adding a little bit of organization rather than dealing with one large .mpx file. Ultimately how you divide things up is somewhat arbitrary and more a matter of personal preference rather than any specifc rules.

To create a folder. Right-click MaxQueueSize – Add – New Folder

new-folder

Do this two times. We will create one folder called Scripts and one called Tasks:

scripts

Now we need to populate our Scripts folders with the two PowerShell scripts we wrote in the ISE earlier.

Right-Click the Scripts folder – Add – New Item

addnewitem

PowerShell script file – Name file – Add

powershell-script-file

Now you can paste in the code we wrote in the PowerShell ISE

increasemaxsize

This takes care of the Increase Max Queue Size PowerShell. Now repeat the steps above for the reset max queue size script:

powershell-scripts

Now we need to populate our Tasks folder

Right-Click Tasks Folder – Add – New Item

add-new-task

Empty Management Pack Fragment – IncreaseMaxQueueSize.mpx – Add

increasetask

The code for a task that kicks off a PowerShell script is pretty easy:


<ManagementPackFragment><SchemaVersion>
=”2.0xmlns:xsd=”http://www.w3.org/2001/XMLSchema“>
<Monitoring>
<Tasks>
<Task ID=”Sample.RegKey.IncreaseMaxQueueSize.AgentTaskAccessibility=”InternalTarget=”SC!Microsoft.SystemCenter.ManagedComputerEnabled=”trueTimeout=”300Remotable=”true“>
<Category>Custom</Category>
<ProbeAction ID=”ProbeTypeID=”Windows!Microsoft.Windows.PowerShellProbe“>
<ScriptName>IncreaseMaxQueueSize.ps1</ScriptName>
<ScriptBody>$IncludeFileContent/Scripts/IncreaseMaxQueueSize.ps1$ </ScriptBody>
<SnapIns />
<Parameters />
<TimeoutSeconds>300</TimeoutSeconds>
<StrictErrorHandling>true</StrictErrorHandling>
</ProbeAction>
</Task>
</Tasks>
</Monitoring>
<LanguagePacks>
<LanguagePack ID=”ENUIsDefault=”true“>
<DisplayStrings>
<DisplayString ElementID=”Sample.RegKey.IncreaseMaxQueueSize.AgentTask“>
<Name>Max Queue Size Increase</Name>
<Description>Increase Max Queue Size Regkey to 75 MB</Description>
</DisplayString>
</DisplayStrings>
</LanguagePack>
</LanguagePacks>
</ManagementPackFragment>


taskxml

You do this for both tasks and associate each with the appropriate PowerShell file.

So Visual Studio will look like this:

regkeymp

And once you build and import the pack you will have two tasks that will show up as options when you are in the Windows Computer State view:

task

If anyone wants these instructions in video form, just post a comment below and I will record a step-by-step video walkthrough.

If the source files or finished MP are helpful again don’t hesitate to ask. Just post a comment and I will zip up the files and upload to TechNet or GitHub.

Tagged , , ,

How do I: Generate a single report of all healthy agents + grey agents +timestamp of last recorded heartbeat?

This week is a training week, which means I have tiny windows of time to catch up on some blogging.

I have had this question a few times over the years. It seems like it should have a straightforward answer, but if there is one, I have not been able to find it.

When customers have asked this in the past I usually refer them to the following three posts:

https://blogs.msdn.microsoft.com/mariussutara/2008/07/24/last-contacted/

http://www.systemcentercentral.com/quicktricks-last-agent-heartbeat/

http://blog.scomskills.com/grey-agents-with-reason-gray-agents/

These do an excellent job in different ways of getting at the question of what agents are greyed out and when did heartbeats stop coming in.

Unfortunately, these do nothing to address the first part of the question, they want all agents, those that have stopped heart beating and also those that haven’t.

This is a little bit more tricky. It is easy enough to get a list of all agents, a list of grey agents, and to query for when health service heartbeat failures occur. But there is nothing easily accessible via the SDK or via the DW that (at least that I am aware of) allows us to capture a timestamp for when a non-grey agents last heartbeat came in.

So my natural question to my customer is why do you need the healthy agents heartbeat timestamp? The answer was basically that they want to feed that data into other systems in their org and they don’t want to deal with two different lists/files. They want one file, but at the end of the day they don’t actually need an exact timestamp for last heartbeat of a healthy agent.

This makes things a lot easier and lends itself to a relatively simple potential solution:

Import-Module OperationsManager

$Agent = get-scomclass -name “Microsoft.SystemCenter.Agent”
$MonitoringObjects = Get-SCOMMonitoringObject $Agent
$Date= Get-Date | Where-Object {$_.ToShortDateString()}
$DateSString= $Date.ToShortDateString()
$TimeLString= $Date.ToLongTimeString()
$DateTimeCombine = $DateSString + ” “ + $TimeLString
$UserDesktop = [Environment]::GetFolderPath(“Desktop”)
 
function GenerateAgentReport

{
    foreach ($object in $MonitoringObjects)
        {
    $result = New-Object –TypeName PSObject
    $result | Add-Member -MemberType NoteProperty -Name DisplayName -Value $object.DisplayName 
    $result | Add-Member -MemberType NoteProperty -Name Agent_Healthy -Value $object.IsAvailable
        if ($object.IsAvailable -contains “True”)
            {
             $result | Add-Member -MemberType NoteProperty -Name LastHeartbeat -Value $DateTimeCombine -PassThru
            }
        else
            {
            $result | Add-Member -MemberType NoteProperty -Name LastHeartbeat -Value $object.AvailabilityLastModified -PassThru
            }
        }
}

GenerateAgentReport | out-gridview

heartbeat

Basically this returns each agent in your management group. If the Agent is greyed out we use the AvailabilityLastModified property to pull an approximate timestamp. If the agent is still heartbeating as determined by the IsAvailable property then the AvailabilityLastModified property isn’t going to contain useful information, so in this case we substitute the current date/time for that field indicating that we have had a successful heartbeat within the past 5 minutes.

I said “approximate timestamp” when referring to agents with an IsAvailable value of false (greyed out agent) in that while in many cases AvailabilityLastModified should correspond to a when a heartbeat failure occurs flipping the agent from healthy to critical. If for some reason the agent was already in a critical state, but was still heartbeating the AvailabilityLastModified property would only be capturing when the agent went into the critical state, not the moment of last heartbeat. If you need a more or less exact moment of last heartbeat report I suggest using one of the links above. But if you need a quick PowerShell report to feed into other systems to help prioritize agent remediation the above script or some modified form of it might be mildly useful.

Tagged , , , ,