Wednesday, December 20, 2017

#OpsMgr: Extract notification information

One of the areas of OpsMgr that often have the biggest impact on others is the notifications and many customers create a large number of notification subscriptions, which sometimes makes it hard to manage.

I created this PowerShell script to help a customer to extract notification information, covering channels, subscribers and subscriptions. The output of the script is an HTML file saved to the highlighted location


############################################################################
#
#   SCOM-NotificationConfigurationReport-htmlout.ps1
#
#   Script by: Vanessa Bruwer
#
#    This script retrieves all notification configurations and outputs as HTML file.
#
############################################################################

# Variables

$ReportDate = Get-Date -format "yyyy-M-dd"

$rnd = Get-Random -minimum 1 -maximum 1000
$ReportLocation = "C:\Temp"
$ReportName = "$ReportDate-$rnd-SCOM-NotificationConfiguration.html"
$SavetoFile = "$ReportLocation\$ReportName"


# there should be no need to update the script beyond this point

# Delete any previous versions of the report for in case

If (Test-Path $SavetoFile){
     Remove-Item $SavetoFile
}


# Open the content
$body = "<font face=Arial><table border=0><tr><td><b>Notification Configuration</b></td></tr><tr><td><font face=Arial>"


# Connect to OperationsManager

Import-Module OperationsManager

$MGName = (get-scommanagementgroup).Name

# Get Channels

$body += "<table border=1 bordercolor=silver width=100%><tr><td colspan=2><b>Channels</b></td></tr>"
$body += "<tr><td><b>Channel Display Name</b></td><td><b>Type</b></td></tr>"

$Channels = Get-SCOMNotificationChannel

foreach ($Channel in $Channels)
{

$ChannelName = $Channel.DisplayName
$ChannelType = $Channel.ChannelType

#Write-Host $ChannelName, $ChannelType

$body += "<tr><td>$ChannelName</td><td>$ChannelType</td></tr>"

}

$body += "</table>"

$body += "<p></p>"


# Get Subscribers

$body += "<table border=1 bordercolor=silver width=100%><tr><td colspan=2><b>Subscribers</b></td></tr>"
$body += "<tr><td><b>Display Name</b></td><td><b>Address Name</b></td></tr>"

$Subscribers = Get-SCOMNotificationSubscriber

foreach ($subscriber in $Subscribers)
{
$Subscribername = $subscriber.Name

$subscriberaddress = ($subscriber.devices).Name


#Write-Host $Subscribername, $subscriberaddress

$body += "<tr><td>$Subscribername</td><td>$subscriberaddress</td></tr>"

}

$body += "</table>"
$body += "<p></p>"


# Get Subscriptions

$body += "<table border=1 bordercolor=silver width=100%><tr><td colspan=4><b>Subscriptions</b></td></tr>"
$body += "<tr><td><b>Display Name</b></td><td><b>Description</b></td><td><b>Enabled</b></td><td><b>Recipients</b></td></tr>"

$subscriptions = Get-SCOMNotificationSubscription

foreach ($subscription in $subscriptions)
{

$subname = $subscription.DisplayName
$subdescription = $subscription.Description
$subEnabled = $subscription.Enabled
$subrecipients = ($subscription.ToRecipients).Name


#Write-Host $subname, $subdescription, $subEnabled, $subrecipients

$body += "<tr><td>$subname</td><td>$subdescription</td><td>$subEnabled</td><td>$subrecipients</td></tr>"
}

$body += "</table>"

$body += "</td></tr></table></font>"

$body >> $SavetoFile


This is a sample of what the output looks like from my lab environment:

notifications

Monday, December 11, 2017

#OpsMgr: script to assist with moving the OperationsManager and OperationsManagerDW databases

It happens from time to time that we need to move the databases used in our System Center Operations Manager environments from one server to another. While this is a very well documented process for both the OperationsManager database and the Data Warehouse database, it often happens that we miss a step somewhere along the line.

To assist with this process, I have created two scripts, a PowerShell script for updating the registry keys on the management servers and restarting the services, and a SQL script for updating the relevant tables in the database.

I have commented the scripts as much as possible, so it should be fairly easy to figure out what to do. I would recommend running the SQL script first, and then the PowerShell one.

Update the variables (highlighted) before running. Scripts have been tested with OpsMgr 2012 and OpsMgr 2016 in a lab environment. Results may vary in production, and it is highly recommended you test in your lab environment before using in production.

---------------------------------------------------------------------------------------------------------------------

SQL Script:

-- Declare the variable to be used.
DECLARE @OpsDBServer nvarchar(255) = '<server name here>',
         @DWDBServer nvarchar(255) = '<server name here>';


Use OperationsManager

UPDATE MT_Microsoft$SystemCenter$ManagementGroup
SET SQLServerName_43FB076F_7970_4C86_6DCA_8BD541F45E3A = @OpsDBServer


UPDATE MT_Microsoft$SystemCenter$OpsMgrDB$AppMonitoring
SET MainDatabaseServerName_5C00C79B_6B71_6EEE_4ADE_80C11F84527A = @OpsDBServer

UPDATE MT_Microsoft$SystemCenter$DataWarehouse
SET MainDatabaseServerName_2C77AA48_DB0A_5D69_F8FF_20E48F3AED0F  = @DWDBServer

UPDATE MT_Microsoft$SystemCenter$DataWarehouse$AppMonitoring
SET MainDatabaseServerName_5C00C79B_6B71_6EEE_4ADE_80C11F84527A  = @DWDBServer


UPDATE MT_Microsoft$SystemCenter$DataWarehouse$AppMonitoring_Log
SET Post_MainDatabaseServerName_5C00C79B_6B71_6EEE_4ADE_80C11F84527A = @DWDBServer

select SQLServerName_43FB076F_7970_4C86_6DCA_8BD541F45E3A from MT_Microsoft$SystemCenter$ManagementGroup
select MainDatabaseServerName_5C00C79B_6B71_6EEE_4ADE_80C11F84527A from MT_Microsoft$SystemCenter$OpsMgrDB$AppMonitoring
select MainDatabaseServerName_2C77AA48_DB0A_5D69_F8FF_20E48F3AED0F from MT_Microsoft$SystemCenter$DataWarehouse
select MainDatabaseServerName_5C00C79B_6B71_6EEE_4ADE_80C11F84527A from MT_Microsoft$SystemCenter$DataWarehouse$AppMonitoring
select Post_MainDatabaseServerName_5C00C79B_6B71_6EEE_4ADE_80C11F84527A from MT_Microsoft$SystemCenter$DataWarehouse$AppMonitoring_Log


sp_configure ‘show advanced options’,1
reconfigure
sp_configure ‘clr enabled’,1
reconfigure


DECLARE @broker integer

set @broker = (SELECT is_broker_enabled FROM sys.databases WHERE name='OperationsManager')

IF @broker = 0
BEGIN
     ALTER DATABASE OperationsManager SET SINGLE_USER WITH ROLLBACK IMMEDIATE
     ALTER DATABASE OperationsManager SET ENABLE_BROKER
     ALTER DATABASE OperationsManager SET MULTI_USER

    PRINT 'Broker version is incorrect.';
END
ELSE
     PRINT 'Broker version is correct.';

GO


Use OperationsManagerDW

UPDATE MemberDatabase SET ServerName = @DWDBServer

select ServerName from MemberDatabase

GO

---------------------------------------------------------------------------------------------------------------------

PowerShell script:

############################################################################
#
#   SCOM-UpdateDBServerLocations.ps1
#
#
#    This script can be used when moving both the OperationsManager and Data Warehouse
#    databases to a new location.
#    The script will update the registry on all management servers.
#    The script should be run once the databases have been migrated and you are ready
#    to make the final updates.
#    User running this script should have full admin rights on all management servers
#    and update rights on both databases.
#
############################################################################

#Variables

$ManagementServers = "ms1,ms2,ms3,ms4" # add management server names comma separated, this creates an array of the management servers

$stopservices = "Yes" # change to no if services are already stopped


$OpsDBServer = "opsdbservername\instancename,port"

$DWDBServer = "dwservername\instancename,port"


$KeyLocation1 = "HKLM:\SOFTWARE\Microsoft\System Center\2010\Common\Database"
$KeyLocation2 = "HKLM:\SOFTWARE\Microsoft\Microsoft Operations Manager\3.0\Setup"


$ReportDate = Get-Date -format "yyyy-M-dd"

$rnd = Get-Random -minimum 1 -maximum 1000
$ReportLocation = "C:\Temp"
$ReportName = "$ReportDate-$rnd-SCOM-DBMigrationLog.csv"
$SavetoFile = "$ReportLocation\$ReportName"


# there should be no need to update the script beyond this point

# Delete any previous versions of the report for in case

If (Test-Path $SavetoFile){
     Remove-Item $SavetoFile
}

# Open the content
$body = @()

$body += "SCOM DB Migration Log - "+$ReportDate



# Stop services on Management Servers

if ($stopservices -eq "Yes")
{
foreach ($ms in $ManagementServers)
{

    (Get-Service -DisplayName 'System Center Data Access Service' -ComputerName $ms).Stop()
     (Get-Service -DisplayName 'System Center Management Configuration'-ComputerName $ms).Stop()
     (Get-Service -DisplayName 'Microsoft Monitoring Agent' -ComputerName $ms).Stop()

$body += "Services stopped on " + $ms

}
}

# sleep for a few seconds
Start-Sleep -s 20


# update registry key values on MS

$cred = Get-Credential

foreach ($ms in $ManagementServers)
{
$session = New-PSSession -Authentication Kerberos -ComputerName $ms  -Credential $cred -Name RegUpdate

Set-ItemProperty -Path $KeyLocation1 -Name DatabaseServerName  -Value $OpsDBServer
Set-ItemProperty -Path $KeyLocation2 -Name DatabaseServerName  -Value $OpsDBServer
Set-ItemProperty -Path $KeyLocation2 -Name DataWarehouseDBServerName  -Value $DWDBServer

Disconnect-PSSession $session

$body += "Registry updated on " + $ms

}


# Start Services on Managment Services

foreach ($ms in $ManagementServers)
{

    (Get-Service -DisplayName 'System Center Data Access Service' -ComputerName $ms).Start()
     (Get-Service -DisplayName 'System Center Management Configuration'-ComputerName $ms).Start()
     (Get-Service -DisplayName 'Microsoft Monitoring Agent' -ComputerName $ms).Start()


$body += "Services stopped on " + $ms
}


# write-report

$body >> $SavetoFile


---------------------------------------------------------------------------------------------------------------------

As always, copy the scripts into Notepad or similar first and make sure the quotes are not mangled.

Thursday, October 19, 2017

#OpsMgr: Bulk deployment of Linux agents via a script

One of my customers had a requirement to deploy in excess of 2000 Linux agents recently, and was looking for a streamlined way of doing this. I found a couple of scripts online that can help with the deployment of the agent, but none that did quite what we needed to do, so I wrote my own.

Pop the list of agents to deploy into a text file and update the script to point to that file. You can also specify the name of the resource pool that should manage these agents. The script will prompt you for the run-as account username and password when you run it, so this is probably not ready to run unattended.

Script pings agent first to make sure it is reachable, and will then attempt to deploy/configure the agent, the same way the discovery does in the console.

Script results are saved into a CSV file, which is also mailed to you.

Update the bits highlighted in yellow before running. I would also recommend doing to pasting via notepad thing to ensure no mangling of quotation marks, etc happen.


#################################################################
#
#   SCOM-Linux-Agent-Discovery-script.ps1
#
#   Script by: Vanessa Bruwer
#
#
#    This script initiates the discovery for a list of Linux servers from a text file.
#    It is to be used for a set of servers to be managed by the Resource Pool
#    specified in this script.
#
#    The script does some prechecking before the server is added to the discovery.
#
#    It is based on the script provided by Operating Quadrant here:
#    https://operatingquadrant.com/2012/12/06/using-powershell-for-automated-unixlinux-agent-discovery/
#
#################################################################

# Parameters

$UserName = Read-Host -Prompt 'Please enter the Linux username'
$Password = Read-Host -Prompt 'Please enter the Linux password'


# Variables

$ResourcePoolName = "Linux Resource Pool"
$AgentFileLoc = "c:\temp\scripts\linuxagentlist.txt"

$sleeptime = "60"      # sleep time in seconds



$FromEmail = ""
$ToEmail = ""
$MailServer = ""


$ReportDate = Get-Date -format "yyyy-M-dd"

$rnd = Get-Random -minimum 1 -maximum 1000
$ReportLocation = "C:\Temp"
$ReportName = "$ReportDate-$rnd-SCOM-linuxagentdiscovery.csv"
$SavetoFile = "$ReportLocation\$ReportName"



# there should be no need to update the script beyond this point


# Delete any previous versions of the report for in case

If (Test-Path $SavetoFile){
     Remove-Item $SavetoFile
}

# Open the content
$body = @()

$body += "Server Name,Ping Response,DiscoveryResult"


# Read the text file
$Agents = get-content $AgentFileLoc


# Connect to Operations Manager

Import-module OperationsManager

$wsmanuser=$UserName
$wsmanpassword = ConvertTo-SecureString $Password -AsPlainText -Force


$WSCredential = New-Object System.Management.Automation.PSCredential ($wsmanuser, $wsmanpassword)
$Pool = Get-SCOMResourcePool -DisplayName $ResourcePoolName

$SSHCredential = Get-SCXSSHCredential -username $UserName –ElevationType sudo

# Set the counters to Zero
$i = 0
$n = 0

# Loop through the pending agents and ping them
foreach ($Agent in $Agents) {

$n = $n+1

   if (test-Connection -ComputerName $Agent -Count 2 -Quiet )
         {
     $Status = "Responds"

    $DiscResult = Invoke-SCXDiscovery -name $Agent -ResourcePool $Pool -WsManCredential $WSCredential -SshCredential $SSHcredential

    $DiscResult | fl Succeeded, ErrorData
     $DiscResult | Install-scxagent

if ($DiscResult.Succeeded){

$DiscStatus = "Success"
}
elseif ($DiscResult.EndpointAlreadyManaged)
{
$DiscStatus = "Skipped, already managed"
}
elseif ($DiscResult.ErrorData){
$DiscStatus = "Error occurred, please investigate"
}


Start-Sleep -s $sleeptime

         }
          else
          {
       $Status = "Unreachable"
       $i = $i+1

      $DiscStatus = "Skipped"
          }


# Write to the report
$ReportOutput = "$Agent,$Status,$DiscStatus"
$body += $ReportOutput
}


$agentcnt = $n-$i

$body >> $SavetoFile

$mbody = "There are $n Linux agents in the text file, $i not pinging and $agentcnt added to discovery"

Write-Host "There are $n Linux agents in the text file, $i not pinging and $agentcnt added to discovery"

Write-Host “Sending Email”


  #Creating a Mail object
      $msg = new-object Net.Mail.MailMessage
      $att = New-Object Net.Mail.Attachment($SavetoFile)

#Creating SMTP server object
      $smtp = new-object Net.Mail.SmtpClient($mailserver)

#Email structure
  $Subject = "SCOM Linux Agent discovery - $ReportDate"

     $msg.From = $FromEmail
      $msg.ReplyTo = $FromEmail
      $msg.To.Add($ToEmail)
      $msg.subject = $Subject
      $msg.body = $mbody
      $msg.Attachments.Add($att)


   #Sending email
     $smtp.Send($msg)

#write-host "Email sent"


And, as always, test in lab before using in production.

Thursday, September 28, 2017

SCSM Unsealed MP backups

I have now also created an updated version of the unsealed MP backup script that works with System Center Service Manager.

You can use this one to schedule your unsealed MP backups on a regular basis. Just update the location of the backup folder (highlighted), save as a .ps1 file and go.

Have tested on SCSM 2012 and SCSM 2016

##############################################################################
#
#   SCSM-UnsealedMP-Backup.ps1
#
#    This script backs up all unsealed management packs to a folder with the backup date as folder name
#
##############################################################################

# Variables

$ReportDate = Get-Date -format "yyyy-M-dd"
$path = "c:\Backups\$ReportDate\"


# there should be no need to update the script beyond this point

# test if the folder exists, and, if not, create it

If (!(Test-Path $path)){
     New-Item -ItemType directory -Path $path
}

# Connect to Service Manager

# Service Manager Administrator Module
$InstallationConfigKey = 'HKLM:\SOFTWARE\Microsoft\System Center\2010\Service Manager\Setup'
$AdminModule = (Get-ItemProperty -Path $InstallationConfigKey -Name InstallDirectory).InstallDirectory + "Powershell\System.Center.Service.Manager.psd1"
Import-Module -Name $AdminModule

#Connect to management server
$ServerConfigKey = 'HKCU:\Software\Microsoft\System Center\2010\Service Manager\Console\User Settings'
$SvcMgmtSrv = (Get-ItemProperty -Path $ServerConfigKey).SDKServiceMachine
New-SCManagementGroupConnection -ComputerName $SvcMgmtSrv


# get all the unsealed management packs and create array

$MPS = Get-SCManagementPack | where {$_.Sealed -eq $false}

# step through the management packs and export them to the folder specified
foreach($mp in $mps)
{
export-SCManagementpack -managementpack $mp -path $path
}



And thanks goes to Matthew Dowst for simplifying the SCSM module loading.

Thursday, September 21, 2017

OpsMgr 2016: Issue with Scheduled Maintenance Mode

I ran into an issue at a customer recently where they were unable to use the scheduled maintenance mode function in the console. When trying to save the schedule, they would receive the following error:

maintenancemodeerror

The error text contains the following:

Microsoft.EnterpriseManagement.Common.ServerDisconnectedException: The client has been disconnected from the server. Please call ManagementGroup.Reconnect() to reestablish the connection. ---> System.ServiceModel.CommunicationObjectFaultedException: The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.


The fix is simple:

Grant sysadmin permissions to the SDK account on the SQL Instance hosting the OperationsManager database.

If you are unable to grant SA rights to this account, you can assign the following rights on the MSDB database:

  • SQLAgentOperatorRole
  • SQLAgentReaderRole
  • SQLAgentUserRole

There is no need to restart services or the console, the fix will work instantly.

Related Posts with Thumbnails