Showing posts with label Powershell. Show all posts
Showing posts with label Powershell. Show all posts

Tuesday, October 3, 2017

SCOM 2012/2016 automated subscribers verification and cleanup

in our SCOM environment, we ended up with a lot of email subscribers - for a lot of users we created a subscriber. and deleting is not possible unless the user is removed from all subscriptions.
so I released already a script to find a subscriber and then remove it from all subscriptions and then delete the subscriber.




this script takes it a step further. it can be used for cleanup of the subscribers (email only).
it will enumerate through all subscribers, check if it has an SMTP subscription, and then try to find the AD user based on the email address (and check if the found user is disabled)
it will then ask you if you want to delete the user (email address)


if you select YES, it will enumerate all subscriptions, and try to find the subscriber (by GUID) and remove it from every subscription. if removal fails with the error "requires at least one recipient" then the entire subscription is deleted. (maybe it would be better to ask first if you want to delete it - but that's up to you- that is pretty easy to implement)








$error.clear()
$ManagementServer = "FQDN"

$Module = get-module|where {$_.Name -match "OperationsManager"}
if (!($Module)){
    Write-Host "Import OperationsManager Module"
    import-module OperationsManager
}

$Module = get-module|where {$_.Name -match "ActiveDirectory"}
if (!($Module)){
    Write-Host "Import ActiveDirectory Module"
    import-module ActiveDirectory
}

Write-Host "Connecting to SCOM Management Group"
$ManagementServer = New-Object Microsoft.EnterpriseManagement.ManagementGroup($ManagementServer)
#popup window object
$YesNo = new-object -comobject wscript.shell


Function DeleteSubscriber
{
    Param ([string]$SubID,
                 [String]$user)
   
    $Subscriptions = Get-SCOMNotificationSubscription
    foreach ($subscription in $Subscriptions)
    {
  $SubscriptionName = $subscription.DisplayName
  $Recipient = $Null
  foreach ($rec in $subscription.ToRecipients)
  {
   If ($rec.id -match $SubID)
   {
   $SubscriptionName + " -- " + $subscription.Enabled.ToString()
   $Recipient = $rec
   }
  }


  #we first have to exit the foreach loop above, otherwise it fails if we delete the user.
  if ($Recipient -ne $Null)
  {
   try
   {
    $subscription.ToRecipients.Remove($Recipient)
    $subscription.Update()
    "deleted $user from" + $subscription.DisplayName
   }
   catch
   {
    if ($error[0].exception -match "requires at least one recipient")
    {
     Get-SCOMNotificationSubscription -Name $subscription.name | Remove-SCOMNotificationSubscription
     "deleted subscription " + $subscription.DisplayName + " because $user was the only recipient"
    }
   }
  }
 }

    "now we delete the subscriber $user with ID " + $SubID
    Get-SCOMNotificationSubscriber -id $SubID | Remove-SCOMNotificationSubscriber
    if ( $error[0].exception -match "Please call ManagementGroup.Reconnect()")
    {
        $ManagementServer.Reconnect()
  "Subscriber $user was not deleted because it still is linked to a subscribtion"
    }
}#END of Function



#Main - let's enumerate all subscribers
$subscribers = Get-SCOMNotificationSubscriber
foreach ($subscriber in $subscribers)
{
    foreach ($protocol in $subscriber.devices)
    {
        if ($protocol.Protocol -eq "Smtp")
        {
            $email = $protocol.Address.tostring()
             $filt = 'mail -eq "' + $email + '"'
             $result = Get-ADUser -filter $filt
            if ($result.enabled -eq $False -and $result -ne $null)
            {

                #the found AD account is disabled, so let's ask the question
                $usr = $protocol.Address
                $subscriber.Name + " -- " + $usr
                $intAnswer = $YesNo.popup("Do you want to delete $usr", 0,"Delete User",4)
                If ($intAnswer -eq 6)
                { #YES delete the user
                    DeleteSubscriber -SubID $subscriber.id -user $usr
                }
                else
                { #No
                    $protocol.Address + " will not be deleted"
                }
           }
           
        }
    }
}







Monday, September 25, 2017

SCOM - remove subscriber from all subscriptions and delete subscriber

when trying to delete a subscriber, you may get an error that the subscriber is still in use. but there is no quick and simple way to view in the SCOM console the memberships for the subscriber....


but there is a simple powershell script that will provide that information.


let's connect to SCOM (I prefer to use the Powershell_ISE console.... ) first:


$MG= "YourManagementServerFQDN"
$Module = get-module|where {$_.Name -match "OperationsManager"}
if (!($Module)){
    Write-Host "Import OperationsManager Module"
    import-module OperationsManager
}
Write-Host "Connecting to SCOM Management Group"
$ManagementServer = New-Object Microsoft.EnterpriseManagement.ManagementGroup($MG)



the next step is to get all subscriptions, and then enumerate the members (and only show those that match the member you are looking for


$a = Get-SCOMNotificationSubscription
foreach ($b in $a)
{
       $ns = $b.DisplayName
       $b.ToRecipients | foreach { If ($_.Name -match "SubscriberName") { Write-Host $ns " --"                   $B.Enabled.ToString() } }
}


when you create a subscriber it automatically picks your domainname \username so in our environment I only search for the username - and I just test it first in the console in the subscriber pane.


but... powershell is to make life easy - so can even be a lot more simple.
In the script below it will find any subscription where the subscribername is found, and it then removes that subscriber from the ToRecipients, and updates the subscription.
and the last step is to remove the subscriber once it has been removed from all subscriptions !!


$a = Get-SCOMNotificationSubscription
$user = "SubscriberName"
foreach ($b in $a)
{
 $ns = $b.DisplayName
 $d = $Null
 foreach ($c in $b.ToRecipients)
 {
   If ($c.Name -match $user)
    {
        Write-Host $ns " -- " $B.Enabled.ToString()
        $d = $C
    }
 }
 if ($d -ne $null)
 {
    $b.ToRecipients.Remove($d)
    $b.Update()
 }
}
write-host "now we delete the subscriber $user"
$del = Get-SCOMNotificationSubscriber -Name "*$user"
Remove-SCOMNotificationSubscriber $del



That's it !







Monday, May 2, 2016

System Center Service Manager 2012 R2 CSV sync by using Import-SCSMClassInstance

Problem: import-SCSMinstance imports objects that are in a specified CSV file, but... it does not remove "obsolete" objects. - I want to really sync - load what is missing, and remove what is obsolete

 if you drop all objects and then import them again, objects get a new GUID, so you lose history for the objects that are imported again, so this is not a preferred solution.

here is how you truly sync (mirror) the objects - this example is a simple class only with displaynames of groups:

Create your CSV file, this should contain all the objects that should be in your class
in my example, I load them from a SQL database:

$query = "select last_name from ca_contact where contact_type=2308"
$connection = new-object system.data.sqlclient.sqlconnection($StrConn);
$adapter = new-object system.data.sqlclient.sqldataadapter ($query, $connection)
$set = new-object system.data.dataset
$adapter.Fill($set)
$table = new-object system.data.datatable
$table = $set.Tables[0]

this is collecting some group names into $table
then create the CSV file and I add the values also to array $csv (I  run a "-contains" against this array - which is not possible against the $table variable)

$csvfile = "C:\SCSMimport\USDGroups.csv"
$csv=@()
Foreach ($R in ($table))
{
 
    Add-Content $csvfile ($R.last_name)
     $csv += $name
}

get all your current objects loaded in SCSM:
$GrpClass = Get-SCSMClass -Name USDgroups
$all = Get-SCSMClassInstance -Class $GrpClass

and now we compare $all against the array that contains anything that should be in the group.
 
foreach ($obj in $all)
{    if ($csv -notcontains $obj.DisplayName)
    {        "obsolete group : " + $obj.DisplayName
        Remove-SCSMClassInstance -Instance $obj
     }
}
 


So.. anything not in the CSV but still loaded in the class in SCSM is now removed from SCSM

and then the last step to ensure new objects are added:
Import-SCSMInstance -DataFileName $csvfile -FormatFileName 'C:\tools\SCSMimport\USDGroups.xml'

 that's it !
 

Thursday, July 4, 2013

OpsMgr 2012 - Subscriptions - selective enabling of subscriptions again

With most of the System Center Operations Manger (2012 and 2007) updates, you have to disable all the subscriptions and enabled them later again.
the examples are for 2012, but just delete the "SCOM" from the poweshell commands, and it should run in 2007.


So disabling of all subscriptions can be done with a one liner in powershell:

Get-SCOMNotificationSubscription | Where {$_.Enabled  -eq $True} | Disable-SCOMNotificationSubscription

however in our environment, we have a lot of subscription, and there is also a number disabled. so enabling all the proper subscriptions again is a painfull slow excercise.... but not anymore....

this simple poweshell creates a logfile with all the subscriptions and their state (so run it before you disable the subscriptions.....)

$log = "D:\Tools\Powershell\subscriptions.txt"
set-content $log ""
$pcs = Get-SCOMNotificationSubscription
foreach ($pc in $pcs)
{
    [string]$entry = $pc.displayname + "," + $pc.enabled
 add-content $log $entry
}


and now when you're done with your tasks, and you want to enable your subscriptions again:

$log = "D:\Tools\Powershell\subscriptions.txt"
$file = get-content $log
foreach ($line in $file)
{
    if ($line -ne "")
    {
        $pc = $line.split(",")
        if ($pc[1] -eq "True")
        {
            Get-SCOMNotificationSubscription -DisplayName $pc[0] |Enable-SCOMNotificationSubscription
        }
    }
}

the script is a bit slow, so it will run for 15 minutes or more, but you can do something else

Regards,
Andre