<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Laura Park’s Microsoft Monitoring Blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/laurapark/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/laurapark/feed.xml</link>
    <description>Posts in this blog are provided &amp;quot;AS IS&amp;quot; with no warranties, and confers no rights. Use of included script samples are subject to the terms specified in the Terms of Use.</description>
    <lastBuildDate>Tue, 16 Apr 2019 06:10:36 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>SCOM Gray Agents in VMM - Report &amp; Email</title>
      <link>https://docs.microsoft.com/archive/blogs/laurapark/scom-gray-agents-in-vmm</link>
      <pubDate>Tue, 25 Sep 2018 14:26:50 GMT</pubDate>
      <dc:creator><![CDATA[Laura Park]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/laurapark/?p=285</guid>
      <description><![CDATA[A customer had a number of agents hosted in VMM, and often a VM would hang after patching. It was...]]></description>
      <content:encoded><![CDATA[A customer had a number of agents hosted in VMM, and often a VM would hang after patching. It was "Running" according to VMM but not actually responsive. This script helped identity these Gray Agents. They also had VMs hosted in Azure, and those were identifiable by naming convention.

It relies on the VMM and SCOM PowerShell modules, and invokes WinRM to check the actual VM state. It has been tested repeatedly in a large SCOM environment (4000+ agents) and typically runs in a few minutes or less.

Example output:
<h2>Gray Agent Report Info</h2>
Script Start Time : 01/01/2018 06:00:00

User Account Used To Produce Report : contoso\scom-adon

&nbsp;
<h2>Gray Agents</h2>
Total Agents in SCOM: 4359

Total Gray Agent count: 11

&nbsp;

9 gray agents in VMM.

- 2 are VMM hosts

- 0 are hung

- 6 are Running

- 1 are in a state other than Running (e.g. Saved, Paused, etc.)

0 gray agents in Azure.

2 gray agents are not in Azure, not in VMM

&nbsp;
<table width="98%">
<tbody>
<tr>
<td><strong>Name</strong></td>
<td><strong>Comment</strong></td>
</tr>
<tr>
<td>VM00.contoso.net</td>
<td>VMM Host</td>
</tr>
<tr>
<td>VM02.contoso.net</td>
<td>VMM Host</td>
</tr>
<tr>
<td>VM25.contoso.net</td>
<td>Server is running</td>
</tr>
<tr>
<td>VM71.contoso.net</td>
<td>Unknown (not Azure or VMM)</td>
</tr>
<tr>
<td>VM35.contoso.net</td>
<td>Server is running</td>
</tr>
<tr>
<td>VM31.contoso.net</td>
<td>Server is running</td>
</tr>
<tr>
<td>VM24.contoso.net</td>
<td>Server is running</td>
</tr>
<tr>
<td>VM20.contoso.net</td>
<td>Server is running</td>
</tr>
<tr>
<td>VM01.contoso.net</td>
<td>Unknown (not Azure or VMM)</td>
</tr>
<tr>
<td>VM04.contoso.net</td>
<td>Saved</td>
</tr>
<tr>
<td>VM38.contoso.net</td>
<td>Server is running</td>
</tr>
</tbody>
</table>
&nbsp;

Total Script Run Time: 0 hrs 1 min 30 sec

&nbsp;

&nbsp;
<pre># Gets all Gray Agents and finds which are hosted in Azure (IaaS VMs), VMM, or other/Unknown.

# Puts list of Gray agent Name and Comment (Azure VM, VMM Host, Server is Running, Server is Hung, ... etc.)

# into Results.csv. Writes gray agent breakdown of total counts in Report.txt. Sends email of HTML report.

#

# Laura.Park@microsoft.com

# August 2017





### Prep

$starttime = get-date



#load VMM module

cd C:\temp\VMM_Module\bin\psModules

Import-Module .\virtualmachinemanager

Get-SCVMMServer -ComputerName vmm1.contoso.com -setasdefault



#load SCOM module

import-module operationsmanager

$connect = New-SCOMManagementGroupConnection –ComputerName managementserver1.contoso.com

####



# variables

$CSVFilePath = "C:\temp\GrayAgentResults$(get-date -f yyyy-MM-dd_HH-mm).csv"  ### Replace with desired file path

$TXTFilePath = "C:\temp\GrayAgentReport$(get-date -f yyyy-MM-dd_HH-mm).txt"   ### Replace with desired file path

$tempTest = 'C:\temp\winrmjob.log'; #log for WinRM tests



# Email variables

$EmailServer =  "smtp.contoso.com"

$EmailTo = "MONEngineers@contoso.com, Admins@contoso.com"

$EmailFrom = "SCOM-HealthCheckReport@contoso.com"

#

$whoami = whoami #account running this script



$colMonitoringObjects = @()



$WindowsAgentClass = Get-SCOMClass -Name "Microsoft.SystemCenter.Agent"

$UXClass = Get-SCClass -name "Microsoft.Unix.Computer"



$WindowsAgents = Get-SCOMMonitoringObject -Class $WindowsAgentClass

$UnixAgents = Get-SCOMMonitoringObject -Class $UXClass

$AgentlessMonitored = (Get-SCOMAgentlessManagedComputer).Computer



$colMonitoringObjects += $WindowsAgents

$colMonitoringObjects += $UnixAgents

$colMonitoringObjects += $AgentlessMonitored

#

$colVMMmanagedcomputers = Get-SCVMMManagedComputer # VMM hosts

$colVMMmanagedcomputers += Get-SCvirtualmachine    # VMM vms



# all Gray Agents in SCOM

$colGrayAgents = $colMonitoringObjects | where {$_.IsAvailable –eq $false} # Mon Obj type



$colVMMGrayAgents = @()       # VMM obj type

$colVMMGrayAgentsMonObj = @() # Mon Obj type

$colAzureGrayAgents = @()     # Mon Obj type

$colUnknownGrayAgents = @()   # DisplayName



$colVMMRunningTEMP = @() # before we know whether a VM is really Running or Hung

$colVMMRunning = @()     # VMM obj type

$colVMMHung = @()        # VMM obj type

$colVMMOtherStatus = @() # VMM obj type

$colVMMHosts = @()       # VMM obj type



# count variables for final Report

$countVMMGrayAgents = 0



# possible gray state causes

$countAzureGrayAgents = 0 # Azure VM

$countUnknownGrayAgents = 0 # Unknown (not in Azure, not in VMM)

$countVMMHung = 0 # hung

$countVMMRunning = 0 # running

$countVMMOtherStatus = 0 # VM is a state other than "Running" or [empty]

$countVMMHosts = 0 # VMM host  (empty status)

#

# Find source (VMM, Azure, neither/unknown) of gray agents

foreach ($agent in $colGrayAgents)

{

    # Separate Azure-hosted gray agents based on naming convention (if applicable)

    if ($agent.DisplayName -like "AZURE*")

    {

        Write-debug "Skipping AzureVM : $($agent.DisplayName)"

        $countAzureGrayAgents++

        $colAzureGrayAgents += $agent

       

    } else { # VMM-hosted gray agents    

        foreach ($vm in $colVMMmanagedcomputers)

        {

            if ($vm.Name -eq $agent.DisplayName)

            {

                $colVMMGrayAgents += $vm

                $colVMMGrayAgentsMonObj += $agent 

                $countVMMGrayAgents++



                Write-verbose "Found #$countVMMGrayAgents gray agent in VMM : $($vm.name) :: VMM Status: $($vm.status)"



                if ($vm.status -eq "Running")

                {

                    $colVMMRunningTEMP += $vm # "TEMP" because need to check with WinRM if VM is actually Running or Hung

               

                } elseif ($vm.status -eq $null)

                {

                    $colVMMHosts += $vm

                    $countVMMHosts = $colVMMHosts.count

                } else

                {

                    $colVMMOtherStatus += $vm

                    $countVMMOtherStatus = $colVMMOtherStatus.count

                }  

                break #inner foreach loop to move onto searching source of next gray $agent

            }

        }

        # if we get to this point, $agent not found in Azure nor VMM

        #$colUnknownGrayAgents += $agent  # see next statement, more efficient

    }

}



# Gray agents that are not hosted in Azure or VMM

$colUnknownGrayAgents = Compare -Ref $colGrayAgents -Diff ($colVMMGrayAgentsMonObj + $colAzureGrayAgents) -Property DisplayName | foreach DisplayName

#display names only

$countUnknownGrayAgents = $colUnknownGrayAgents.count



# How long did this script take to up to this point?

$CheckTime1=Get-Date

$Check1RunTime=$CheckTime1-$StartTime



write-verbose "Completed finding source (VMM, Azure, unknown) of all gray agents"

write-verbose " - Checkpoint 1 Runtime: $($Check1RunTime.hours) hrs $($Check1RunTime.minutes) min $($Check1RunTime.seconds) seconds"



#### Write Partial Results to .csv File

# - up to this point we have all Gray Agents in various $col* variables

# - still need to check the "Running" VMM VMs

# - write the current results up to this point to file



# write the Azure gray agent VMs to Results.csv

$temp1 = @()

$colAzureGrayAgents | ForEach-Object {

    $row1 = "" | Select "Name","Comment"

    $row1."Name" = $_.DisplayName

    $row1."Comment" = "Azure VM"

    $temp1 += $row1

}

$temp1 | Export-Csv $CSVFilePath -NoTypeInformation



# write the Unknown VMs (not Azure or VMM) to Results.csv

$temp2 = @()

$colUnknownGrayAgents | ForEach-Object {

    $row2 = "" | Select "Name","Comment"

    $row2."Name" = $_# .DisplayName

    $row2."Comment" = "Unknown (not Azure or VMM)"

    $temp2 += $row2

}

$temp2 | Export-Csv $CSVFilePath -Append -NoTypeInformation



# write the VMM Hosts to Results.csv

$temp3 = @()

$colVMMHosts | ForEach-Object {

    $row3 = "" | Select "Name","Comment"

    $row3."Name" = $_.name # VMM obj type

    $row3."Comment" = "VMM Host"

    $temp3 += $row3

}

$temp3 | Export-Csv $CSVFilePath -Append -NoTypeInformation



# write the VMM other status ("Paused", "Saved", "PowerOff", etc.) to Results.csv

$temp4 = @()

$colVMMOtherStatus | ForEach-Object {

    $row4 = "" | Select "Name","Comment"

    $row4."Name" = $_.name # VMM obj type

    $row4."Comment" = $_.status

    $temp4 += $row4

}

$temp4 | Export-Csv $CSVFilePath -Append -NoTypeInformation

#### End of writing partial results



# How long did this script take to up to this point?

$CheckTime2=Get-Date

$Check2RunTime=$CheckTime2-$StartTime



write-verbose "Completed writing partial results to file. Beginning VMM running/hung state checks. This may take a while."

write-verbose " - Checkpoint 2 Runtime: $($Check2RunTime.hours) hrs $($Check2RunTime.minutes) min $($Check2RunTime.seconds) seconds"



####

# WinRM check on "Running" VMM VMs

$originalErrActionPref = $ErrorActionPreference

$ErrorActionPreference = "SilentlyContinue"



$checkcount = 0



#region WinRM Test - Remote Jobs (Batch/Parallel invocation) -- (thank you Arlu!)

try {

    $remoteJobQueue = [System.Collections.Queue]::Synchronized((New-Object System.Collections.Queue));

    $colVMMRunningTEMP | % {$remoteJobQueue.Enqueue($_);}

    $maxAllowed = 30; #number of jobs allowed per batch

    $maxTime = 15; #max time allowed for the whole job process (minutes)

    $allJobs = @();

    $jobArray = @();

    $timeOut = [datetime]::Now.AddMinutes($maxTime);

    $batchNumber = 1;

    while ($remoteJobQueue.Count -gt 0 -and ([datetime]::Now -lt $timeOut)) {

        Write-Verbose "Starting batch $batchNumber. $($remoteJobQueue.Count) remaining in queue." -Verbose;

        $jobArray = @();

        while ($jobArray.Count -lt $maxAllowed) {

            if ($remoteJobQueue.Count -eq 0) {

                Write-Verbose "Queue is empty" -Verbose;

                break;

            }

            $remoteVm = $remoteJobQueue.Dequeue();

            Write-Verbose "Starting test for $($remoteVm.Name). $($remoteJobQueue.Count) remaining in the queue." -Verbose;

            $jobArray += Invoke-Command -ComputerName $remoteVm.Name -ScriptBlock { return $true } -AsJob;

            Write-Verbose "Remote job count: $($jobArray.Count)" -Verbose;

        }

        Write-Verbose "Waiting for batch $batchNumber to complete" -Verbose;

        $null = Wait-Job -Job $jobArray -Timeout 120 -ErrorAction SilentlyContinue;

        Write-Verbose "All jobs in batch $batchNumber are completed." -Verbose;

        $allJobs += $jobArray;   

        $batchNumber++;

    }



    #Get result from all remote jobs.

    foreach ($job in $allJobs) {

        if ($job.state -eq 'Completed') {

            $colVMMRunning += $colVMMRunningTEMP | ? { $_.Name -eq $job.Location };

            Write-Verbose "WinRM connection successful - $($job.Location) server is running";

        }

        else {       

            $colVMMHung += $colVMMRunningTEMP | ? { $_.Name -eq $job.Location };

            Write-Verbose "WinRM connection failed - $($job.Location) server is hung";

        }

    }

    Get-Job | Remove-Job -Force -ErrorAction SilentlyContinue;

}

catch {   

    $errorMsg =  "Error encounter during WinRM test process: $($_.Exception.Message)";

    "{0}: {1}" -f [datetime]::Now.ToString('MMddyyy:hh:mm:ss'),$errorMsg | Out-File $tempTest

    throw "Error encounter during WinRM test process: $($_.Exception.Message)";

}

#endregion



$countVMMRunning = $colVMMRunning.count

$countVMMHung = $colVMMHung.count



$ErrorActionPreference = $originalErrActionPref

### End of WinRM check



Write-verbose "Completed all $checkcount VMM running/hung checks"

$CheckTime3=Get-Date

$Check3RunTime=$CheckTime3-$StartTime

write-verbose " - Checkpoint 3 Runtime: $($Check3RunTime.hours) hrs $($Check3RunTime.minutes) min $($Check3RunTime.seconds) seconds"



### Write final results to .csv file

$temp5 = @()

$colVMMRunning | ForEach-Object {

    $row5 = "" | Select "Name","Comment"

    $row5."Name" = $_.name # VMM obj type

    $row5."Comment" = "Server is running"

    $temp5 += $row5

}

$temp5 | Export-Csv $CSVFilePath -Append -NoTypeInformation



$temp6 = @()

$colVMMHung | ForEach-Object {

    $row6 = "" | Select "Name","Comment"

    $row6."Name" = $_.name # VMM obj type

    $row6."Comment" = "Server is hung"

    $temp6 += $row6

}

$temp6 | Export-Csv $CSVFilePath -Append -NoTypeInformation

### End of writing results to .csv file



### Write .txt Report with final counts

$txt = "Total Agents in SCOM:  $($colMonitoringObjects.count - $AgentlessMonitored.count)"

$txt += "`nTotal Gray Agent count*:  $($colGrayAgents.count)"

$txt += "`n(*may include gray Agentless objects)`n"

$txt += "`nBreakdown of Gray Agents:"



if ($countVMMGrayAgents -ge $countAzureGrayAgents){

    # most gray agents are in VMM

    $txt += "`n`t$countVMMGrayAgents gray agents in VMM. Further breakdown:"

    $txt += "`n`t`t- $countVMMHosts are VMM hosts"

    $txt += "`n`t`t- $countVMMHung are hung"

    $txt += "`n`t`t- $countVMMRunning are Running"

    $txt += "`n`t`t- $countVMMOtherStatus are in a state other than Running (e.g. Saved, Paused, etc.)"

    $txt += "`n`n`t$countAzureGrayAgents gray agents in Azure."

} else { # most gray agents are in Azure

    $txt += "`n`t$countAzureGrayAgents gray agents in Azure."

    $txt += "`n`n`t$countVMMGrayAgents gray agents in VMM. Further breakdown:"

    $txt += "`n`t`t- $countVMMHosts are VMM hosts"

    $txt += "`n`t`t- $countVMMHung are hung"

    $txt += "`n`t`t- $countVMMRunning are Running"

    $txt += "`n`t`t- $countVMMOtherStatus are in a state other than Running (e.g. Saved, Paused, etc.)"

}



$txt += "`n`n`t$countUnknownGrayAgents gray agents are not in Azure, not in VMM"

$txt += "`n`nEnd of report"

$txt | out-file $TXTFilePath

### End of writing .txt Report



### Interactive output



# see matched VMM vms name and status in VMM

write-verbose "`nGray agents in VMM and their Status:`n"

$colVMMGrayAgents | select name, status | Format-Table



write-verbose "`nGray agents in Azure:`n"

$colAzureGrayAgents | select displayname | Format-Table



# including Agent + Agentless

write-verbose "`nFound $($colMonitoringObjects.count) agents/agentless in SCOM ( $($WindowsAgents.count) Windows, $($UnixAgents.count) Unix, $($AgentlessMonitored.count) Agentless)"



# not including Agentless

write-verbose "Found $($colMonitoringObjects.count - $AgentlessMonitored.count) agents in SCOM ( $($WindowsAgents.count) Windows, $($UnixAgents.count) Unix, not including Agentless)"



Write-verbose "Found $($colGrayAgents.count) gray agents in SCOM"

#Write-verbose "Found $($colVMMmanagedcomputers.count) VMs in VMM"

Write-verbose "Found $countVMMGrayAgents gray agents in VMM"

Write-verbose "Found $countAzureGrayAgents agents in Azure"

# count of agents not in VMM or Azure

$countUnknownGrayAgents = $colGrayAgents.count - ($countVMMGrayAgents + $countAzureGrayAgents)

Write-verbose "Found $countUnknownGrayAgents gray agents not in VMM or Azure (unknown)"



###

# How long did this script take to up to this point?

$CheckTime5=Get-Date

$Check5RunTime=$CheckTime5-$StartTime



write-verbose "Completed writing results to file. Beginning email report."

write-verbose " - Checkpoint 5 Runtime: $($Check5RunTime.hours) hrs $($Check5RunTime.minutes) min $($Check5RunTime.seconds) seconds"



# Create header for HTML Report

$Head = "&lt;style&gt;"

$Head +="BODY{background-color:#CCCCCC;font-family:Verdana,sans-serif; font-size: small;}"

$Head +="TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse; width: 98%;}"

$Head +="TH{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:#293956;color:white;padding: 5px; font-weight: bold;text-align:left;}"

$Head +="TD{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:#F0F0F0; padding: 2px;}"

$Head +="&lt;/style&gt;"



#beginning of HTML content:



#Section to insert the Script Generic info

$ReportOutput += "&lt;h2&gt;Gray Agent Report Info&lt;/h2&gt;"

$ReportOutput += "&lt;p&gt;Script Start Time      :  $StartTime&lt;/p&gt;"

$ReportOutput += "&lt;p&gt;User Account Used To Produce Report      :  $WhoAmI&lt;/p&gt;"



$ReportOutput += "&lt;br&gt;"

$ReportOutput += "&lt;h2&gt;Gray Agents&lt;/h2&gt;"



$ReportOutput += "&lt;p&gt;Total Agents in SCOM:  $($colMonitoringObjects.count - $AgentlessMonitored.count)&lt;/p&gt;"

$ReportOutput += "&lt;p&gt;Total Gray Agent count:  $($colGrayAgents.count)&lt;/p&gt;"

$ReportOutput += "&lt;br&gt;"

$ReportOutput += "&lt;p&gt;$countVMMGrayAgents gray agents in VMM.&lt;/p&gt;"

$ReportOutput += "&lt;p&gt;-  $countVMMHosts are VMM hosts&lt;/p&gt;"

$ReportOutput += "&lt;p&gt;-  $countVMMHung are hung&lt;/p&gt;"

$ReportOutput += "&lt;p&gt;- $countVMMRunning are Running&lt;/p&gt;"

$ReportOutput += "&lt;p&gt;- $countVMMOtherStatus are in a state other than Running (e.g. Saved, Paused, etc.)&lt;/p&gt;"

$ReportOutput += "&lt;p&gt;$countAzureGrayAgents gray agents in Azure.&lt;/p&gt;"

$ReportOutput += "&lt;p&gt;$countUnknownGrayAgents gray agents are not in Azure, not in VMM&lt;/p&gt;"

$ReportOutput += "&lt;br&gt;"





# Gray Agent Table

$ReportOutput += ($temp1 + $temp2 + $temp3 + $temp4 + $temp5 + $temp6) | Sort-Object Name  | Select Name, Comment| ConvertTo-HTML -fragment



# How long did this script take to run?

$EndTime=Get-Date

$TotalRunTime=$EndTime-$StartTime



# Close the Body of the Report

$ReportOutput += "&lt;br&gt;"

$ReportOutput += "&lt;p&gt;Total Script Run Time: $($TotalRunTime.hours) hrs $($TotalRunTime.minutes) min $($TotalRunTime.seconds) sec&lt;/p&gt;"

$ReportOutput += "&lt;/body&gt;"



# Save the Final Report to a File (HTML)

#ConvertTo-HTML -head $Head -body "$ReportOutput" | Out-File $ReportPath



# Send Final Report by email...

Write-verbose "Emailing Report"

$SMTPServer = $EmailServer

$SmtpClient = New-Object Net.Mail.SmtpClient($smtpServer)



$Body = ConvertTo-HTML -head $Head -body "$ReportOutput"

$mailmessage = New-Object system.net.mail.mailmessage

$mailmessage.from = $EmailFrom

$mailmessage.To.add($EmailTo)



$mailmessage.Subject = "SCOM Gray Agent Report"

$MailMessage.IsBodyHtml = $true

$mailmessage.Body = $Body

#$smtpclient.Send($mailmessage)

Send-MailMessage -To $mailmessage.To -Subject $mailmessage.Subject -From $mailmessage.From -Body $mailmessage.Body -SmtpServer $EmailServer -BodyAsHtml -Encoding $mailmessage.BodyEncoding



# How long did this script take to up to this point?

$CheckTime6=Get-Date

$Check6RunTime=$CheckTime6-$StartTime



write-verbose "Script complete."

write-verbose " - Total Runtime: $($Check6RunTime.hours) hrs $($Check6RunTime.minutes) min $($Check6RunTime.seconds) seconds"

# end of script</pre>]]></content:encoded>
    </item>
    <item>
      <title>Script to delete decommissioned servers in SCOM</title>
      <link>https://docs.microsoft.com/archive/blogs/laurapark/script-to-delete-decommissioned-servers-in-scom</link>
      <pubDate>Tue, 25 Sep 2018 14:17:44 GMT</pubDate>
      <dc:creator><![CDATA[Laura Park]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/laurapark/?p=275</guid>
      <description><![CDATA[This is a modified version of Tim McFadden's script. This script will take a text file containing...]]></description>
      <content:encoded><![CDATA[This is a modified version of <a target="_blank" href="https://www.scom2k7.com/how-to-delete-scom-2012-r2-managed-computers-using-powershell/" rel="noopener">Tim McFadden's script</a>. This script will take a text file containing the FQDNs of agents which need to be removed from SCOM. Note this process is for when a server has been decommissioned but was never removed from SCOM. If you are instead trying to remove the agent from a server that's still running, you should use Uninstall-SCOMAgent. Otherwise, they'll show up again under Pending Management.

Example usage: .\thisscript.ps1 -MS localhost -path "C:\temp\decommServers.txt"

Example output:
GAC Version Location
--- ------- --------
True v2.0.50727 C:\Windows\assembly\GAC_MSIL\Microsoft.EnterpriseManag...
True v2.0.50727 C:\Windows\assembly\GAC_MSIL\Microsoft.EnterpriseManag...
File contains 3 server names
Connecting to management group
Getting agent managed computers
Checking for ladc.lapfe.com
- Matched ladc.lapfe.com
Checking for bogus.lapfe.com
Checking for laapp1.lapfe.com
- Matched laapp1.lapfe.com
Deleting agents
2 Agents deleted

&nbsp;
<pre># Script to delete decommissioned servers (where uninstall is not possible)
# Laura.Park@microsoft.com
# May 2017
# Based off of https://www.scom2k7.com/how-to-delete-scom-2012-r2-managed-computers-using-powershell/

[CmdletBinding()] 
param (
    [Parameter(Mandatory=$True, 
    ValueFromPipeline=$True, 
    ValueFromPipelineByPropertyName=$True, 
    HelpMessage='What is the SCOM Management Server name?')] 
    [Alias("MS")] 
    [string[]]$MSserver,

    [Parameter(Mandatory=$True, 
    ValueFromPipeline=$True, 
    ValueFromPipelineByPropertyName=$True, 
    HelpMessage='Allows you to specify a text file containing agent FQDNs')] 
    [string[]]$Path
)

[System.Reflection.Assembly]::Load("Microsoft.EnterpriseManagement.Core, Version=7.0.5000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
[System.Reflection.Assembly]::Load("Microsoft.EnterpriseManagement.OperationsManager, Version=7.0.5000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")

function New-Collection ( [type] $type ) 
{
    $typeAssemblyName = $type.AssemblyQualifiedName;
    $collection = new-object "System.Collections.ObjectModel.Collection``1[[$typeAssemblyName]]";
    return ,($collection);
}

$deleteList = get-content -Path $path

write-output "File contains $($deleteList.count) server names"

# Connect to management group
Write-output "Connecting to management group"

$ConnectionSetting = New-Object Microsoft.EnterpriseManagement.ManagementGroup($MSServer)
$admin = $ConnectionSetting.GetAdministration()


Write-output "Getting agent managed computers"
$agentManagedComputers = $admin.GetAllAgentManagedComputers()

# Get list of agents to delete
foreach ($name in $deleteList) 
{
    Write-output "Checking for $name"
    foreach ($agent in $agentManagedComputers)
    {
        if ($deleteCollection -eq $null) 
        {
            $deleteCollection = new-collection $agent.GetType()
        }

        if (@($agent.PrincipalName -eq $name))
        {
            Write-output "- Matched $name"
            $deleteCollection.Add($agent)
            break
        }
    }
}

if ($deleteCollection.Count -gt 0) 
{
    Write-output "Deleting agents"
    $admin.DeleteAgentManagedComputers($deleteCollection)
    if($?){ Write-output "$($deleteCollection.count) Agents deleted" }
}</pre>]]></content:encoded>
    </item>
    <item>
      <title>Verifying PowerShell versions...let me count the ways</title>
      <link>https://docs.microsoft.com/archive/blogs/laurapark/verifying-powershell-versions-let-me-count-the-ways</link>
      <pubDate>Sun, 26 Aug 2018 13:46:58 GMT</pubDate>
      <dc:creator><![CDATA[Laura Park]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/laurapark/?p=245</guid>
      <description><![CDATA[There are numerous posts out there on how to check which version(s) of PowerShell are installed on a...]]></description>
      <content:encoded><![CDATA[There are numerous posts out there on how to check which version(s) of PowerShell are installed on a machine.

An easy, common way is to check the <a href="https://blogs.technet.microsoft.com/heyscriptingguy/2014/10/13/powertip-check-version-of-powershell/">PSVersion property of the $PSVersionTable variable</a>. This will tell you the version of the currently running engine.

But what if you have multiple engines installed on the machine? It's possible (today) to have up to <strong>three</strong> versions of PowerShell installed, side-by-side. Version 2, 3-5, and 6 (core).

[caption id="attachment_255" align="aligncenter" width="1024"]<a target="_blank" href="https://msdnshared.blob.core.windows.net/media/2018/08/ps.png" rel="noopener"><img src="https://msdnshared.blob.core.windows.net/media/2018/08/ps-1024x571.png" alt="" width="1024" height="571" class="wp-image-255 size-large" /></a> Three versions of PS, v2, v4, v6, running side-by-side on the same machine.[/caption]

&nbsp;

Contrary to some posts out there online, I have found that registry keys such as HKLM:\Software\Microsoft\Windows\PowerShell\1\PowerShellEngine do not validate the existence of PowerShell 2.0. In this screenshot, I show a machine which shows that regkey yet I cannot launch the v2 engine.

[caption id="attachment_265" align="aligncenter" width="1185"]<img src="https://msdnshared.blob.core.windows.net/media/2018/08/ps2.png" alt="" width="1185" height="430" class="wp-image-265 size-full" /> Existence of PS v2 regkey but PS v2 engine unavailable.[/caption]

&nbsp;

I've written a script to launch a job in the v2 engine, and using that to verify if v2 is actually available. I use this script to verify the existence of versions on my machines. I then use the other regkeys to verify if higher versions are available. This is just a sample script and could use a lot more testing. But it's been accurate for my small lab and has detected versions 2 through 6.

&nbsp;


<pre># See what version(s) of PowerShell are installed, if any
# v2, v3+, and Core can all exist side-by-side

$originalErrorActionPref = $ErrorActionPreference
$ErrorActionPreference = "SilentlyContinue"

#Reg Installation path for v1 and v2 - does NOT mean it's actually available though
$regPathV1or2 = "hklm:\SOFTWARE\Microsoft\PowerShell\1\PowerShellEngine\"

# Reg path for v3 and above
$regPathV3plus = "hklm:\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine\"

# Reg path for Core
$regPathVCore = "hklm:\SOFTWARE\Microsoft\PowerShellCore\InstalledVersions"

$vOutput = @{ name="";
    v1="";
    v2="";
    v3="";
    v4="";
    v5="";
    v6="";
}

# test for v1 or v2
if (test-path $regPathV1or2)
{
    [string]$versionA = (Get-ItemProperty -path $regPathV1or2).powershellversion

    if ($PSVersionTable.PSVersion.Major -le $versionA)
    { # running v1 or v2 only
        if ($PSVersionTable.PSVersion.Major -eq 1) {
            $vOutput.v1 = $PSVersionTable.PSVersion.ToString()
        } else {
            $vOutput.v2 = $PSVersionTable.PSVersion.ToString()
        }
    } else {
        # machines with v2 only don't have -psversion parameter
        $job = Start-Job {Get-DateTime} -PSVersion 2.0
        if($?) {
             $vOutput.v2 = $versionA
        } else {# no v2 installed
           remove-job $job.id
        }
    }
}

# test for v3 or above
if (test-path $regPathV3plus) 
{
    [string]$versionB = (Get-ItemProperty -path $regPathV3plus).powershellversion

    if($PSVersionTable.PSVersion.Major -eq 3) {
        $vOutput.v3 = $versionB
    } elseif($PSVersionTable.PSVersion.Major -eq 4) {
        $vOutput.v4 = $versionB
    } elseif($PSVersionTable.PSVersion.Major -eq 5) {
        $vOutput.v5 = $versionB
    }
}

# test for Core ----------test-------------------
if (test-path $regPathVCore)
{
    $vOutput.v6 = "Core"
}


$vOutput.name = "$(hostname).$((Get-WmiObject win32_computersystem).Domain)"

#Write-Output $vOutput
write-output "$($vOutput.name);$($vOutput.v1);$($vOutput.v2);$($vOutput.v3);$($vOutput.v4);$($vOutput.v5);$($vOutput.v6)"

$ErrorActionPreference = $originalErrorActionPref</pre>]]></content:encoded>
    </item>
    <item>
      <title>A high-level comparison of monitoring Active Directory with SCOM / OMS Log Analytics and Azure AD Connect Health</title>
      <link>https://docs.microsoft.com/archive/blogs/laurapark/a-high-level-comparison-of-monitoring-active-directory-with-scom-oms-log-analytics-and-azure-ad-connect-health</link>
      <pubDate>Fri, 20 Jul 2018 10:01:03 GMT</pubDate>
      <dc:creator><![CDATA[Laura Park]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/laurapark/?p=215</guid>
      <description><![CDATA[I wrote up this comparison to highlight the key capabilities and differences in each. It's not...]]></description>
      <content:encoded><![CDATA[I wrote up this comparison to highlight the key capabilities and differences in each. It's not intended to be an exhaustive list, but as a way to start the conversation.

Note that all the info here is current as of July 2018. Things change all the time, so take that into consideration!

&nbsp;
<table width="815">
<tbody>
<tr>
<td colspan="3" width="815"><strong>
Active Directory Monitoring Comparison </strong></td>
</tr>
<tr>
<td width="109"></td>
<td width="327"><em>System Center Operations Manager</em></td>
<td width="379"><em>Azure-based solutions (<a href="https://docs.microsoft.com/en-us/azure/active-directory/connect-health/active-directory-aadconnect-health">Azure AD Connect Health</a>, <a href="https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/monitoring-overview-azure-monitor">Azure Monitor</a>, <a href="https://docs.microsoft.com/en-us/azure/log-analytics/log-analytics-overview">OMS Log Analytics</a>)</em></td>
</tr>
<tr>
<td width="109"><strong>Active Directory Health State</strong></td>
<td width="327">
<ul>
 	<li>Monitors based on Availability, Performance, Configuration, Security
<ul>
 	<li>AD Forest, Domain, Site, SiteLink, Connection object, Domain controller computer</li>
</ul>
</li>
 	<li>Key Monitoring Scenarios include:
<ul>
 	<li>Multi-Forest Monitoring</li>
 	<li>Replication</li>
 	<li>Essential Services</li>
 	<li>Trust Monitoring</li>
 	<li>Directory Service Availability</li>
 	<li>Active Directory Database Monitoring</li>
 	<li>Time Skew Monitoring</li>
 	<li>Active Directory Web Service Monitoring</li>
 	<li>Domain Controller Performance</li>
 	<li>Domain Member Perspective</li>
</ul>
</li>
</ul>
</td>
<td width="379">&nbsp;

&nbsp;
<ul>
 	<li>Azure Resource Health (for IaaS VM): <span><a href="https://docs.microsoft.com/en-us/azure/service-health/resource-health-overview">https://docs.microsoft.com/en-us/azure/service-health/resource-health-overview</a></span></li>
 	<li>OMS offers a wide variety of solutions and on-demand assessments, including <span style="font-family: inherit;font-size: inherit"><a href="https://docs.microsoft.com/en-us/azure/log-analytics/log-analytics-ad-assessment">AD Assessment</a></span><span style="font-family: inherit;font-size: inherit"> and </span><span style="font-family: inherit;font-size: inherit"><a href="https://docs.microsoft.com/en-us/azure/log-analytics/log-analytics-ad-replication-status">AD Replication Status</a></span><span style="font-family: inherit;font-size: inherit">, and other features beyond the scope of AD monitoring</span>
<ul>
 	<li><span style="font-family: inherit;font-size: inherit">AD Assessment (solution) will</span><span style="font-family: inherit;font-size: inherit"> </span><span style="font-family: inherit;font-size: inherit">assess the risk and health of your server environments on a regular interval. </span><span style="font-family: inherit;font-size: inherit"> </span><span style="font-family: inherit;font-size: inherit">This solution provides a prioritized list of recommendations specific to your deployed server infrastructure. The recommendations are categorized across four focus areas, which help you quickly understand the risk and take action.</span></li>
 	<li><span style="font-family: inherit;font-size: inherit">AD Replication Status (solution) regularly monitors your Active Directory environment for any replication failures</span></li>
 	<li><span style="font-family: inherit;font-size: inherit"><a href="https://docs.microsoft.com/en-us/services-hub/health/index">On-Demand Assessment’s Services Hub</a></span><span style="font-family: inherit;font-size: inherit"> portal, Executive Summary presentations, and optional PFE engineer delivery</span></li>
 	<li><span style="font-family: inherit;font-size: inherit"><a href="https://aka.ms/assessment_setup_service">https://aka.ms/assessment_setup_service</a></span></li>
</ul>
</li>
 	<li>Azure AD Connect Health: <span style="font-family: inherit;font-size: inherit"><a href="https://docs.microsoft.com/en-us/azure/active-directory/connect-health/active-directory-aadconnect-health">https://docs.microsoft.com/en-us/azure/active-directory/connect-health/active-directory-aadconnect-health</a></span>
<ul>
 	<li>Monitoring alerts to detect when domain controllers are unhealthy and email notifications for critical alerts</li>
 	<li>The Domain Controllers dashboard, which provides a quick view of the health and operational status of your domain controllers</li>
 	<li>The Replication Status dashboard that has the latest replication information and links to troubleshooting guides when errors are detected</li>
 	<li>Quick anywhere access to performance data graphs of popular performance counters, which are necessary for troubleshooting and monitoring purposes</li>
</ul>
</li>
</ul>
</td>
</tr>
<tr>
<td width="109"><strong> Data collection </strong></td>
<td width="327">
<ul>
 	<li>Collects:
<ul>
 	<li>performance counters and events, including (not full list):
<ul>
 	<li>AD Database size</li>
 	<li>Primary domain controller (PDC) emulator master availability</li>
 	<li>Replication latency or queue size</li>
 	<li>Available disk space for drive hosting the Active Directory database</li>
</ul>
</li>
</ul>
</li>
</ul>
</td>
<td width="379">&nbsp;

&nbsp;

&nbsp;
<ul>
 	<li>OMS can collect:
<ul>
 	<li>Performance data</li>
 	<li> <span><a href="https://docs.microsoft.com/en-us/azure/log-analytics/log-analytics-data-sources-windows-events">Windows event logs</a></span></li>
 	<li>Custom logs</li>
 	<li>IIS logs</li>
 	<li>Syslog events</li>
 	<li>AD Assessment (solution):
<ul>
 	<li>Registry</li>
 	<li>LDAP</li>
 	<li>.NET Framework</li>
 	<li>Event log</li>
 	<li>Active Directory Service interfaces (ADSI)</li>
 	<li>Windows PowerShell</li>
 	<li>File data</li>
 	<li>Windows Management Instrumentation (WMI)</li>
 	<li>DCDIAG tool API</li>
 	<li>File Replication Service (NTFRS) API</li>
 	<li>Custom C# code</li>
</ul>
</li>
</ul>
</li>
 	<li>Azure AD Connect Health can collect:
<ul>
 	<li>Disk Space Usage</li>
 	<li>Domain Services Threads in Use</li>
 	<li>Kerberos Authentications/sec</li>
 	<li>LDAP Active Threads</li>
 	<li>LDAP Bind Time</li>
 	<li>LDAP Searches/sec</li>
 	<li>LDAP Successful Binds/sec</li>
 	<li>LSASS Performance</li>
 	<li>NTML Authentication/sec</li>
 	<li>Replication Queue</li>
 	<li>TCP Connections Established</li>
 	<li>Used Memory (%)</li>
 	<li>Used Processor (%)</li>
</ul>
</li>
</ul>
</td>
</tr>
<tr>
<td width="109"><strong>Alerting</strong></td>
<td width="327">
<ul>
 	<li>Monitor-based alerts</li>
 	<li>Event-based alerts</li>
 	<li>Performance (metric)-based alerts</li>
 	<li>Typically &lt;1 minute alerting latency</li>
</ul>
</td>
<td width="379">&nbsp;

&nbsp;

&nbsp;
<ul>
 	<li>Metric Alerts (new) by Azure Monitor:
<ul>
 	<li>includes OMS logs</li>
 	<li><span><a href="https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/monitoring-overview-unified-alerts">https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/monitoring-overview-unified-alerts</a></span></li>
 	<li><span><a href="https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/monitoring-near-real-time-metric-alerts">https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/monitoring-near-real-time-metric-alerts</a></span></li>
 	<li>1-5 minute current latency</li>
</ul>
</li>
 	<li>Azure Monitor classic alerts
<ul>
 	<li><span><a href="https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/insights-alerts-portal">https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/insights-alerts-portal</a></span></li>
</ul>
</li>
 	<li>OMS:
<ul>
 	<li>Includes routed Diagnostics logs</li>
 	<li><span><a href="https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/monitoring-overview-alerts">https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/monitoring-overview-alerts</a></span></li>
 	<li>SLA of 6hrs; usually 10-15 min latency</li>
 	<li>Log Analytics alerts will automatically be extended into the new unifed alerts (see above) on May 14, 2018 <span><a href="https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/monitoring-alerts-extend">https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/monitoring-alerts-extend</a></span></li>
 	<li>AD Assessment (solution) collects data on the domain controller and forwards data to Log Analytics every 7 days</li>
 	<li>AD Replication Status (solution) collects data on the agent and forward data to Log Analytics every 5 days</li>
</ul>
</li>
</ul>
</td>
</tr>
<tr>
<td width="109"><strong>Data visualization</strong></td>
<td width="327">&nbsp;

&nbsp;

&nbsp;
<ul>
 	<li>Use the SCOM console or web console</li>
 	<li>Built-in management pack dashboards, views:
<ul>
 	<li>Active Alerts, Events, All Performance Data, Health State views</li>
 	<li>Topology diagram</li>
 	<li>Inter-Site Replication Traffic</li>
 	<li>Replication performance</li>
 	<li>ATQ Thread Pool Metrics</li>
 	<li>Database and Log Overview</li>
 	<li>Database Size</li>
 	<li>DC/GC Response</li>
 	<li>DC OS Metrics Overview</li>
 	<li>DC Response Time</li>
 	<li>AD Database and Log Disk Space</li>
 	<li>Global Catalog Response/Search Time</li>
 	<li>PDC Response Times</li>
 	<li>LSASS Processor Time</li>
 	<li>Memory Metrics</li>
 	<li>OpMaster Performance</li>
</ul>
</li>
 	<li>Built-in management pack reports:
<ul>
 	<li>AD DC Replication Bandwidth</li>
 	<li>DC Disk Space Chart</li>
 	<li>AD Domain Changes</li>
 	<li>Event Analysis by Event ID</li>
</ul>
</li>
 	<li>Ability to custom author dashboards, views, reports</li>
 	<li>Ability to directly query OpsMgr database and datawarehouse</li>
</ul>
</td>
<td width="379">
<ul>
 	<li>Azure AD Connect Health:
<ul>
 	<li>Domain Controllers Dashboard</li>
 	<li>Replication Status Dashboard</li>
 	<li>Performance Monitors List</li>
</ul>
</li>
 	<li>OMS:
<ul>
 	<li>AD Assessment (solution)
<ul>
 	<li>Summary information for focus areas is shown on the AD Health Check dashboard for the infrastructure in your environment</li>
</ul>
</li>
 	<li>AD Replication Status (solution)
<ul>
 	<li>Replication Errors,  Destination Server Status and Source Server Status, Tombstone Lifetime</li>
</ul>
</li>
 	<li>Assessment solutions:
<ul>
 	<li>Services Hub portal</li>
 	<li><span><a href="https://serviceshub.uservoice.com/knowledgebase/articles/1862968-on-demand-assessment-executive-summary">Executive Summary presentation (PowerPoint)</a></span></li>
 	<li><span><a href="https://serviceshub.uservoice.com/knowledgebase/articles/1862977-download-all-on-demand-assessment-recommendations">Recommendations Plan report (Excel)</a></span></li>
</ul>
</li>
 	<li>Log Analytics</li>
 	<li>View Designer</li>
 	<li>PowerBI</li>
 	<li>Service Map</li>
</ul>
</li>
</ul>
</td>
</tr>
<tr>
<td width="109"><strong>Administrative effort</strong></td>
<td width="327">
<ul>
 	<li>Installing and tuning the AD management pack
<ul>
 	<li>With both SCOM and Azure, a key part of monitoring is knowing what you want to monitor/collect</li>
</ul>
</li>
</ul>
</td>
<td width="379">&nbsp;

&nbsp;

&nbsp;
<ul>
 	<li>Install agent for Azure AD Connect Health for AD DS
<ul>
 	<li><span><a href="https://docs.microsoft.com/en-us/azure/active-directory/connect-health/active-directory-aadconnect-health-agent-install#installing-the-azure-ad-connect-health-agent-for-ad-ds">https://docs.microsoft.com/en-us/azure/active-directory/connect-health/active-directory-aadconnect-health-agent-install#installing-the-azure-ad-connect-health-agent-for-ad-ds</a></span></li>
 	<li>Requirements:  <span><a href="https://docs.microsoft.com/en-us/azure/active-directory/connect-health/active-directory-aadconnect-health-agent-install#requirements">https://docs.microsoft.com/en-us/azure/active-directory/connect-health/active-directory-aadconnect-health-agent-install#requirements</a></span></li>
</ul>
</li>
 	<li>Enabling OMS
<ul>
 	<li>Perform health check using AD Assessment (Solution):
<span><a href="https://docs.microsoft.com/en-us/azure/log-analytics/log-analytics-ad-assessment">https://docs.microsoft.com/en-us/azure/log-analytics/log-analytics-ad-assessment</a></span></li>
 	<li>Install and configure the AD Replication Status (solution), install agents to send the replication data to Log Analytics:  <span><a href="https://docs.microsoft.com/en-us/azure/log-analytics/log-analytics-ad-replication-status#ad-replication-status-data-collection-details">https://docs.microsoft.com/en-us/azure/log-analytics/log-analytics-ad-replication-status#ad-replication-status-data-collection-details</a></span></li>
 	<li>Assessment solutions are automatically refreshed with new data and recommendations every week</li>
 	<li>For Windows VMs, add the extension to the VM Resource Manager template or use PowerShell: <span><a href="https://docs.microsoft.com/en-us/azure/virtual-machines/windows/extensions-oms">https://docs.microsoft.com/en-us/azure/virtual-machines/windows/extensions-oms</a></span></li>
 	<li>For Linux VMs, add the extension to the VM Resource Manager template or use Azure CLI: <span><a href="https://docs.microsoft.com/en-us/azure/virtual-machines/linux/extensions-oms">https://docs.microsoft.com/en-us/azure/virtual-machines/linux/extensions-oms</a></span></li>
 	<li>Configure data sources from the Data menu in Log Analytics Advanced Settings (any configuration is delivered to all connected sources in your workspace)</li>
</ul>
</li>
</ul>
</td>
</tr>
<tr>
<td width="109"><strong>Data retention</strong></td>
<td width="327">
<ul>
 	<li>Two databases: OpsMgr database and Data Warehouse</li>
 	<li>OpsMgr database holds 7 days by default</li>
 	<li>Data Warehouse holds 400 days by default</li>
</ul>
</td>
<td width="379">&nbsp;

&nbsp;

&nbsp;
<ul>
 	<li>Azure AD Connect Health does not generate reports, perform analytics, or provide insights beyond 30 days. Therefore, Azure AD Connect Health does not store, process, or retain any data beyond 30 days. This design is compliant with the GDPR regulations, Microsoft privacy compliance regulations, and Azure AD data retention policies.</li>
 	<li>Log Analytics has a retention age of 31 to 730 days</li>
</ul>
</td>
</tr>
</tbody>
</table>
&nbsp;

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>Troubleshooting SCOM discovery - a thorough how-to</title>
      <link>https://docs.microsoft.com/archive/blogs/laurapark/troubleshooting-scom-discovery-a-thorough-how-to</link>
      <pubDate>Fri, 11 May 2018 16:49:37 GMT</pubDate>
      <dc:creator><![CDATA[Laura Park]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/laurapark/?p=105</guid>
      <description><![CDATA[Something not getting discovered? Objects not appearing in the console after importing a management...]]></description>
      <content:encoded><![CDATA[Something not getting discovered? Objects not appearing in the console after importing a management pack?

Too often it turns out the wrong version of the product's management pack was imported, or a typo in the Run As Account credentials. So double-, triple-check:

<strong>Do you have the right management pack? Do you have the right account credentials?</strong>

&nbsp;

Only then follow these steps:

&nbsp;
<ul>
 	<li>Determine the seed discovery class for the management pack. This is the first class that gets populated after the MP is imported.
<ul>
 	<li>To do this, look up all the discovery rules in the MP. You can find these discovery rules by finding your MP on SystemCenterCore.com or use the MPViewer tool. In this example, I'll use SystemCenterCore.com.</li>
 	<li>We're looking for the seed discovery rule. The seed discovery rule usually says “seed” somewhere in the name. But if this is missing, you can also find it because it’s typically the only discovery that targets a more common class:
<ul>
 	<li>Here's a screenshot from SystemCenterCore.com (note, this is a non-Microsoft website) showing all the discoveries in the Microsoft BizTalk Server 2013 MP</li>
 	<li>Look at the "Target" column for all these discoveries:
<ul>
 	<li><img src="https://msdnshared.blob.core.windows.net/media/2018/05/1-Discoveries.png" alt="" width="882" height="427" class="alignnone size-full wp-image-115" /></li>
</ul>
</li>
 	<li>We see one discovery rule that targets Windows Computers, a 'common' class. This is our seed discovery; the one that all the other discovery rules depend on.</li>
</ul>
</li>
</ul>
</li>
 	<li>Find the Class name that the seed discovery rule discovers/populates (this is NOT the same as the Target)
<ul>
 	<li><img src="https://msdnshared.blob.core.windows.net/media/2018/05/2-Class.png" alt="" width="479" height="338" class="alignnone wp-image-125 size-full" /></li>
 	<li>In this example, the class name is <strong>Microsoft.BizTalk.Server.2013.BizTalkInstallation</strong></li>
</ul>
</li>
</ul>
<ul>
 	<li style="list-style-type: none">
<ul>
 	<li>In the SCOM console, Monitoring Pane, Discovered Inventory view – <strong>Change</strong> <strong>Target Type</strong> (see right-side Task pane) of this view to the <strong>class name</strong> you just found. This will show us if the seed class has populated.
<ul>
 	<li><img src="https://msdnshared.blob.core.windows.net/media/2018/05/3-ChangeTarget.png" alt="" width="610" height="171" class="alignnone wp-image-135 size-full" /></li>
</ul>
</li>
 	<li>If there are no results, the seed discovery is not working. If there are results, the seed discovery IS working, but perhaps a subsequent discovery rule is not, or the other view you were using is not populating correctly.
<ul>
 	<li>Check that the discovery rules are enabled</li>
 	<li>Check if the MP uses a Run As account: check the Distribution of the account and all appropriate agents have this account distributed to them</li>
 	<li>Look in the OpsMgr event log on an agent and verify it has downloaded the MP (filter for event ID 1201 - the event description includes MP name and version)</li>
 	<li>Check the frequency/interval of the discovery rule – has enough time passed?</li>
 	<li>Finally, after confirming everything above – look at the actual configuration of the discovery rule. You can see this in the Authoring pane, MPViewer, or SystemCenterCore.com. The raw XML will show you what the rule looks for on the agent. Usually it’s a registry key. Verify the agent has this.
<ul>
 	<li>&lt;Continuing the example with screenshots from SystemCenterCore.com:&gt;</li>
 	<li><img src="https://msdnshared.blob.core.windows.net/media/2018/05/4-Code.png" alt="" width="989" height="978" class="alignnone wp-image-145 size-full" /></li>
</ul>
</li>
 	<li>At this point, if everything is verified – Run As Account, healthy Agent, existence of registry key…you’re best off opening a support case because something is going wrong! Possibly the management group has stopped processing configuration. But in my experience, 98% of the time, some step above has been missed. Double check everything.</li>
</ul>
</li>
</ul>
</li>
</ul>]]></content:encoded>
    </item>
    <item>
      <title>A high-level comparison of monitoring Windows OS with SCOM / OMS and Azure</title>
      <link>https://docs.microsoft.com/archive/blogs/laurapark/a-high-level-comparison-of-monitoring-windows-os-with-scom-oms-and-azure</link>
      <pubDate>Fri, 11 May 2018 16:24:48 GMT</pubDate>
      <dc:creator><![CDATA[Laura Park]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/laurapark/?p=95</guid>
      <description><![CDATA[A customer wants to move their core OS monitoring off of SCOM and over to OMS or another Azure-based...]]></description>
      <content:encoded><![CDATA[A customer wants to move their core OS monitoring off of SCOM and over to OMS or another Azure-based solution.  I wrote up this comparison to highlight the key capabilities and differences in each. It's not intended to be an exhaustive list, but as a way to start the conversation.

Note that all the info here is current as of April 2018. Things change all the time, so take that into consideration!

&nbsp;
<table width="815">
<tbody>
<tr>
<td colspan="3" width="815">&nbsp;

<strong>Core OS Monitoring Comparison </strong></td>
</tr>
<tr>
<td width="109"></td>
<td width="327"><em>System Center Operations Manager</em></td>
<td width="379"><em>Azure-based solutions (<a href="https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/monitoring-overview-azure-monitor">Azure Monitor</a>, <a href="https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/azure-diagnostics">Azure Diagnostics</a>, <a href="https://docs.microsoft.com/en-us/azure/log-analytics/log-analytics-overview">OMS Log Analytics</a>)</em></td>
</tr>
<tr>
<td width="109"><strong>Windows Computer Health State</strong></td>
<td width="327">
<ul>
 	<li>Monitors based on Availability, Performance, Configuration, Security</li>
</ul>
</td>
<td width="379">&nbsp;

&nbsp;
<ul>
 	<li>Azure Resource Health: <a href="https://docs.microsoft.com/en-us/azure/service-health/resource-health-overview">https://docs.microsoft.com/en-us/azure/service-health/resource-health-overview</a></li>
 	<li>SCOM vs OMS Log Analytics: <a href="https://docs.microsoft.com/en-us/azure/operations-management-suite/operations-management-suite-monitoring-product-comparison">https://docs.microsoft.com/en-us/azure/operations-management-suite/operations-management-suite-monitoring-product-comparison</a></li>
 	<li>OMS offers a wide variety of other solutions and assessments, including Service Map, and other features beyond the scope of OS monitoring</li>
</ul>
</td>
</tr>
<tr>
<td width="109"><strong> Data collection </strong></td>
<td width="327">
<ul>
 	<li>Collects:
<ul>
 	<li>performance counters,</li>
 	<li>event logs,</li>
 	<li>probe/script-based rules</li>
</ul>
</li>
</ul>
</td>
<td width="379">&nbsp;

&nbsp;
<ul>
 	<li>Use Azure Monitor for host-level monitoring: <a href="https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/monitoring-overview-metrics">https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/monitoring-overview-metrics</a></li>
 	<li>Use Azure Diagnostics or OMS for guest VM operating system monitoring</li>
 	<li>Azure Diagnostics can collect:
<ul>
 	<li>Performance data</li>
 	<li>Application logs</li>
 	<li>Windows Event logs</li>
 	<li>Custom error logs created by app or service</li>
 	<li>.NET Event source</li>
 	<li>IIS logs</li>
 	<li>ETW traces</li>
 	<li>Crash dumps</li>
 	<li>Azure diagnostics infrastructure logs</li>
</ul>
</li>
 	<li>OMS can collect:
<ul>
 	<li>Performance data</li>
 	<li>Windows event logs</li>
 	<li>Custom logs</li>
 	<li>IIS logs</li>
 	<li>Syslog events</li>
</ul>
</li>
</ul>
</td>
</tr>
<tr>
<td width="109"><strong>Alerting</strong></td>
<td width="327">
<ul>
 	<li>Monitor-based alerts</li>
 	<li>Event-based alerts</li>
 	<li>Performance (metric)-based alerts</li>
 	<li>Typically &lt;1 minute alerting latency</li>
</ul>
</td>
<td width="379">&nbsp;

&nbsp;
<ul>
 	<li>Metric Alerts (new) by Azure Monitor:
<ul>
 	<li>includes OMS logs</li>
 	<li><a href="https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/monitoring-overview-unified-alerts">https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/monitoring-overview-unified-alerts</a></li>
 	<li><a href="https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/monitoring-near-real-time-metric-alerts">https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/monitoring-near-real-time-metric-alerts</a></li>
 	<li>1-5 minute current latency</li>
</ul>
</li>
 	<li>Azure Monitor classic alerts
<ul>
 	<li><a href="https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/insights-alerts-portal">https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/insights-alerts-portal</a></li>
</ul>
</li>
 	<li>OMS:
<ul>
 	<li>Includes routed Diagnostics logs</li>
 	<li><a href="https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/monitoring-overview-alerts">https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/monitoring-overview-alerts</a></li>
 	<li>SLA of 6hrs; usually 10-15 min latency</li>
 	<li>Log Analytics alerts will automatically be extended into the new unifed alerts (see above) on May 14, 2018 <a href="https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/monitoring-alerts-extend">https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/monitoring-alerts-extend</a></li>
</ul>
</li>
</ul>
&nbsp;</td>
</tr>
<tr>
<td width="109"><strong>Data visualization</strong></td>
<td width="327">
<ul>
 	<li>Use the SCOM console or web console</li>
 	<li>Built-in dasbhoards, views, reports</li>
 	<li>Ability to custom author dashboards, views, reports</li>
 	<li>Queries OpsMgr database and datawarehouse</li>
</ul>
</td>
<td width="379">&nbsp;

&nbsp;
<ul>
 	<li>Azure Monitor:
<ul>
 	<li>Azure portal</li>
 	<li>Ability to custom author views, charts</li>
 	<li>Azure Monitor Metrics Explorer (preview)</li>
</ul>
</li>
 	<li>OMS:
<ul>
 	<li>Log Analytics</li>
 	<li>View Designer</li>
 	<li>PowerBI</li>
 	<li>Service Map</li>
</ul>
</li>
 	<li>Azure Diagnostics:
<ul>
 	<li>Route data to Azure Application Insights</li>
 	<li>Route data to Microsoft PowerBI</li>
 	<li>Route the data to a third-party visualization tool using either live streaming or by having the tool read from an archive in Azure storage</li>
</ul>
</li>
</ul>
</td>
</tr>
<tr>
<td width="109"><strong>Administrative effort</strong></td>
<td width="327">
<ul>
 	<li>Installing and tuning the management pack
<ul>
 	<li>With both SCOM and Azure, a key part of monitoring is knowing what you want to monitor/collect</li>
</ul>
</li>
</ul>
</td>
<td width="379">&nbsp;

&nbsp;
<ul>
 	<li>Enabling Azure Diagnostics
<ul>
 	<li>Add the extension to the VM Resource Manager template: <a href="https://docs.microsoft.com/en-us/azure/virtual-machines/windows/extensions-diagnostics-template?toc=%2fazure%2fvirtual-machines%2fwindows%2ftoc.json">https://docs.microsoft.com/en-us/azure/virtual-machines/windows/extensions-diagnostics-template?toc=%2fazure%2fvirtual-machines%2fwindows%2ftoc.json</a></li>
 	<li>Use PowerShell to enable the extension: <a href="https://docs.microsoft.com/en-us/azure/virtual-machines/windows/ps-extensions-diagnostics">https://docs.microsoft.com/en-us/azure/virtual-machines/windows/ps-extensions-diagnostics</a></li>
 	<li>Use Visual Studio to enable the extension: <a href="https://docs.microsoft.com/en-us/azure/vs-azure-tools-diagnostics-for-cloud-services-and-virtual-machines#turn-on-diagnostics-on-azure-virtual-machines">https://docs.microsoft.com/en-us/azure/vs-azure-tools-diagnostics-for-cloud-services-and-virtual-machines#turn-on-diagnostics-on-azure-virtual-machines</a></li>
</ul>
</li>
 	<li>Enabling OMS
<ul>
 	<li>For Windows VMs, add the extension to the VM Resource Manager template or use PowerShell: <a href="https://docs.microsoft.com/en-us/azure/virtual-machines/windows/extensions-oms">https://docs.microsoft.com/en-us/azure/virtual-machines/windows/extensions-oms</a></li>
 	<li>For Linux VMs, add the extension to the VM Resource Manager template or use Azure CLI: <a href="https://docs.microsoft.com/en-us/azure/virtual-machines/linux/extensions-oms">https://docs.microsoft.com/en-us/azure/virtual-machines/linux/extensions-oms</a></li>
 	<li>Configure data sources from the Data menu in Log Analytics Advanced Settings (any configuration is delivered to all connected sources in your workspace)</li>
</ul>
</li>
</ul>
</td>
</tr>
<tr>
<td width="109"><strong>Data retention</strong></td>
<td width="327">
<ul>
 	<li>Two databases: OpsMgr database and Data Warehouse</li>
 	<li>OpsMgr database holds 7 days by default</li>
 	<li>Data Warehouse holds 400 days by default</li>
</ul>
</td>
<td width="379">&nbsp;
<ul>
 	<li>Archive Azure Diagnostics Logs or Azure Monitor data to storage account to retain forever (or specify retention age)</li>
 	<li>Log Analytics has a retention age of 31 to 730 days</li>
</ul>
</td>
</tr>
</tbody>
</table>]]></content:encoded>
    </item>
    <item>
      <title>Search SCOM subscriptions for a specific string</title>
      <link>https://docs.microsoft.com/archive/blogs/laurapark/search-scom-subscriptions-for-a-specific-string</link>
      <pubDate>Wed, 05 Jul 2017 16:05:22 GMT</pubDate>
      <dc:creator><![CDATA[Laura Park]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/laurapark/?p=85</guid>
      <description><![CDATA[Today I made this simple script for a customer. It searches all notification subscriptions in your...]]></description>
      <content:encoded><![CDATA[Today I made this simple script for a customer. It searches all notification subscriptions in your SCOM management group for a specific string.

This script will look at subscriptions' display name, description, and criteria. Matched results are printed out in green, and added to an array which is returned at the end of the script.
<pre><code># Searches the display name, description, and criteria fields of all SCOM Subscriptions
#
# Laura.Park@microsoft.com
# July 5, 2017

New-SCOMManagementGroupConnection -ComputerName MyManagementServer.contoso.com</code> $searchStr = Read-Host "What are you looking for?" # get all subscriptions $allSub = Get-SCOMNotificationSubscription $resultSub = @() foreach ($sub in $allSub) { if ( ($sub.DisplayName -like "*$searchStr*") -or ($sub.Description -like "*$searchStr*") ) { write-host "Found your string in subscription name or description:`n`t$($sub.DisplayName)`t`t$sub" -ForegroundColor Green $resultSub += $sub continue } if ($sub.Configuration.Criteria -like "*$searchStr*") { write-host "Found your string in subscription criteria:`n`t$($sub.DisplayName)`t`t$sub" -ForegroundColor Green $resultSub += $sub } } $resultSub</pre>]]></content:encoded>
    </item>
    <item>
      <title>Effective monitoring in SCOM</title>
      <link>https://docs.microsoft.com/archive/blogs/laurapark/effective-monitoring-in-scom</link>
      <pubDate>Tue, 06 Dec 2016 14:05:59 GMT</pubDate>
      <dc:creator><![CDATA[Laura Park]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/laurapark/?p=1</guid>
      <description><![CDATA[&nbsp;

Occasionally, a customer requests a full list of the monitoring on a specific agent - all...]]></description>
      <content:encoded><![CDATA[&nbsp;

Occasionally, a customer requests a full list of the monitoring on a specific agent - all rules, monitors, thresholds, and overrides.  While <a href="https://technet.microsoft.com/en-us/library/hh212748(v=sc.12).aspx">the task called "Show Running Rules and Monitors for this Health Service"</a> will be helpful, it does not show thresholds or overridden thresholds.

For this, you can use the PowerShell cmdlet: <a href="https://technet.microsoft.com/en-us/library/hh918465(v=sc.30).aspx">Export-SCOMEffectiveMonitoringConfiguration</a>. Here's a sample script:

<span style="color: #ff4500;font-family: Lucida Console;font-size: xx-small">$Members</span><span style="font-family: Lucida Console;font-size: xx-small"> </span><span style="color: #a9a9a9;font-family: Lucida Console;font-size: xx-small">=</span><span style="font-family: Lucida Console;font-size: xx-small"> (</span><span style="color: #0000ff;font-family: Lucida Console;font-size: xx-small">Get-SCOMGroup</span><span style="font-family: Lucida Console;font-size: xx-small"> </span><span style="color: #000080;font-family: Lucida Console;font-size: xx-small">–DisplayName</span><span style="font-family: Lucida Console;font-size: xx-small"> </span><span style="color: #8b0000;font-family: Lucida Console;font-size: xx-small">"My SCOM group"</span><span style="font-family: Lucida Console;font-size: xx-small">)</span><span style="color: #a9a9a9;font-family: Lucida Console;font-size: xx-small">.</span><span style="font-family: Lucida Console;font-size: xx-small">GetRelatedMonitoringObjects()</span>

<span style="color: #ff4500;font-family: Lucida Console;font-size: xx-small">$Members</span><span style="font-family: Lucida Console;font-size: xx-small"> </span><span style="color: #a9a9a9;font-family: Lucida Console;font-size: xx-small">|</span><span style="font-family: Lucida Console;font-size: xx-small"> </span><span style="color: #0000ff;font-family: Lucida Console;font-size: xx-small">ForEach-Object</span><span style="font-family: Lucida Console;font-size: xx-small"> { </span><span style="color: #0000ff;font-family: Lucida Console;font-size: xx-small">Export-SCOMEffectiveMonitoringConfiguration</span><span style="font-family: Lucida Console;font-size: xx-small"> </span><span style="color: #000080;font-family: Lucida Console;font-size: xx-small">–Instance</span><span style="font-family: Lucida Console;font-size: xx-small"> </span><span style="color: #ff4500;font-family: Lucida Console;font-size: xx-small">$_</span><span style="font-family: Lucida Console;font-size: xx-small"> </span><span style="color: #000080;font-family: Lucida Console;font-size: xx-small">-Path</span><span style="font-family: Lucida Console;font-size: xx-small"> </span><span style="color: #8b0000;font-family: Lucida Console;font-size: xx-small">"C:\thresholds\</span><span style="font-family: Lucida Console;font-size: xx-small">$(</span><span style="color: #ff4500;font-family: Lucida Console;font-size: xx-small">$_</span><span style="color: #a9a9a9;font-family: Lucida Console;font-size: xx-small">.</span><span style="font-family: Lucida Console;font-size: xx-small">DisplayName)</span><span style="color: #8b0000;font-family: Lucida Console;font-size: xx-small">.csv"</span><span style="font-family: Lucida Console;font-size: xx-small"> </span><span style="color: #000080;font-family: Lucida Console;font-size: xx-small">–RecurseContainedObjects</span><span style="font-family: Lucida Console;font-size: xx-small">} </span>

Take a minute to understand the lines above. Look at the TechNet site for <a href="https://technet.microsoft.com/en-us/library/hh918465(v=sc.30).aspx">Export-SCOMEffectiveMonitoringConfiguration</a> to understand the cmdlet's parameters, like "-RecurseContainedObjects."

I suggest testing this on a small group of agents first.  Once an agent is processed, a .csv file will appear in the path specified, "C:\thresholds\" in this example.

Once you've gotten the .csv files, you'll notice it's not very pretty - all the content is in the first column.  So to make things more usable and better looking, just do "Text to Columns" in Excel:

&nbsp;

[caption id="attachment_35" align="alignnone" width="1024"]<img width="1024" height="145" class="wp-image-35 size-large" alt="First, select the entire first column in the spreadsheet. Then, click &quot;Text to Columns.&quot;" src="https://msdnshared.blob.core.windows.net/media/2016/12/effectivemon-data-1024x145.png" /> First, select the entire first column in the spreadsheet. Then, click "Text to Columns."[/caption]

&nbsp;

&nbsp;

[caption id="attachment_55" align="alignnone" width="1024"]<img width="1024" height="412" class="wp-image-55 size-large" alt="Use the pipeline character '|' as the delimiter." src="https://msdnshared.blob.core.windows.net/media/2016/12/effectivemon-data21-1024x412.png" /> Use the pipeline character '|' as the delimiter.[/caption]

That's it, enjoy!  Now you can send off this spreadsheet to whoever thought they really wanted to know the details of the hundreds of monitors and rules that were running on this agent :)]]></content:encoded>
    </item>
  </channel>
</rss>