OpsMgrExtendedAdminTasks.psm1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
Function Backup-OMManagementPacks
{
<#
 .Synopsis
  Backup OpsMgr management packs using OpsMgr SDK
 
 .Description
  Backup OpsMgr sealed and unsealed management packs using OpsMgr SDK. A boolean value $true will be returned if the backup has been successful, otherwise, a boolean value of $false is returned if any there are any errors occurred during the backup process.
 
 .Parameter -SDKConnection
  OpsMgr SDK Connection object (SMA connection or hash table).
 
 .Parameter -SDK
  Management Server name
 
 .Parameter -UserName
  Alternative user name to connect to the management group (optional).
 
 .Parameter -Password
  Alternative password to connect to the management group (optional).
 
 .Parameter -BackupLocation
  MP Backup Location.
 
 .Parameter -BackupSealedMP
  Set this parameter true to backup sealed management packs as well (exported into unsealed XMLs).
 
 .Parameter -RetentionDays
  Number of retention days for the management pack backup.
 
 .Example
  # Connect to OpsMgr management group via management server "OpsMgrMS01" using current user's credentials and then backup both sealed and unsealed management packs to \\server\backup, with 3 retention days:
  Backup-OMManagementPacks -SDK "OpsMgrMS01" -BackupLocation "\\server\backup" -BackupSealedMP -RetentionDays 3
 
 .Example
  # Connect to OpsMgr management group via management server "OpsMgrMS01" using alternative credentials and then backup both sealed and unsealed management packs to \\server\backup, with 3 retention days:
  $Password = ConvertTo-SecureString -AsPlainText "password1234" -force
  Backup-OMManagementPacks -SDK "OpsMgrMS01" -Username "domain\SCOM.Admin" -Password $Password -BackupLocation "\\server\backup" -BackupSealedMP $true -RetentionDays 3
 
 .Example
  # Connect to OpsMgr management group the SMA connection "OpsMgrSDK_TYANG" and then backup both sealed and unsealed management packs to \\server\backup, with 3 retention days:
  $SDKCOnnection = Get-AutomationConnection "OpsMgrSDK_TYANG"
  Backup-OMManagementPacks -SDKConnection $SDKConnection -BackupLocation "\\server\backup" -BackupSealedMP $true -RetentionDays 3
#>

    [CmdletBinding()]
    PARAM (
        [Parameter(ParameterSetName='SMAConnection',Mandatory=$true,HelpMessage='Please specify the SMA Connection object')][Alias('Connection','c')][Object]$SDKConnection,
        [Parameter(ParameterSetName='IndividualParameter',Mandatory=$true,HelpMessage='Please enter the Management Server name')][Alias('DAS','Server','s')][String]$SDK,
        [Parameter(ParameterSetName='IndividualParameter',Mandatory=$false,HelpMessage='Please enter the user name to connect to the OpsMgr management group')][Alias('u')][String]$Username = $null,
        [Parameter(ParameterSetName='IndividualParameter',Mandatory=$false,HelpMessage='Please enter the password to connect to the OpsMgr management group')][Alias('p')][SecureString]$Password = $null,
        [Parameter(Mandatory=$true,HelpMessage='Please enter backup location')][String]$BackupLocation,
        [Parameter(Mandatory=$false,HelpMessage='Also backup sealed management packs')][Boolean]$BackupSealedMP = $false,
        [Parameter(Mandatory=$true,HelpMessage='Please enter retention days')][String]$RetentionDays
    )

    #Connect to MG
    If ($SDKConnection)
    {
        Write-Verbose "Connecting to Management Group via SDK $($SDKConnection.ComputerName)`..."
        $MG = Connect-OMManagementGroup -SDKConnection $SDKConnection
        $SDK = $SDKConnection.ComputerName
        $Username = $SDKConnection.Username
        $Password= ConvertTo-SecureString -AsPlainText $SDKConnection.Password -force
    } else {
        Write-Verbose "Connecting to Management Group via SDK $SDK`..."
        If ($Username -and $Password)
        {
            $MG = Connect-OMManagementGroup -SDK $SDK -UserName $Username -Password $Password
        } else {
            $MG = Connect-OMManagementGroup -SDK $SDK
        }
    }

    #Management Group Name
    $MGName = $MG.Name

    #Check Backup Location
    If ((Test-Path $BackupLocation))
    {
        #backup should be located in a sub folder with the name of the management group
        $BackupLocation = Join-Path $BackupLocation $MGName
        If (!(Test-Path $BackupLocation))
        {
            New-Item -type directory -Path $BackupLocation | Out-Null
        }

        $date = Get-Date
        $BackupSubDir = "$($date.day)-$($date.month)-$($date.year) $($date.hour)`.$($date.minute)`.$($date.second)"
        $BackupDir = Join-Path $BackupLocation $BackupSubDir
        $UnsealedBackupDir = Join-Path $BackupDir 'Unsealed'
        $SealedBackupDir = Join-Path $BackupDir 'Sealed'
        #Create Backup Directory structure
        New-Item -type directory -Path $BackupDir | Out-Null
        New-Item -type directory -Path $UnsealedBackupDir | Out-Null
        New-Item -type directory -Path $SealedBackupDir | Out-Null
    
        #Get MPs
        If ($BackupSealedMP){
            Write-Verbose 'INFO: Backing up both sealed and unsealed management packs'
            #Get all sealed and unsealed MPs
            $arrMPs = $MG.GetManagementPacks()
        
            #Create a MPXMLWriter for sealed MPs
            Write-Verbose 'Creating ManagementPackXmlWriter object for backing up sealed management packs.'
            Try {
                $SealedmpWriter = new-object Microsoft.EnterpriseManagement.Configuration.IO.ManagementPackXmlWriter($SealedBackupDir)
            } Catch {
                $BackupMPErrors += "Unable to create a ManagementPackXmlWriter object for location: $SealedBackupDir`."
            }
        } else {
            Write-Verbose 'Backing up only unsealed management packs'
            $strMPquery = "Sealed = 'false'"
            $mpCriteria = New-Object  Microsoft.EnterpriseManagement.Configuration.ManagementPackCriteria($strMPquery)
            $arrMPs = $MG.GetManagementPacks($mpCriteria)
        }

        #Create a MPXMLWriter for unsealed MPs
        Write-Verbose 'Creating ManagementPackXmlWriter object for backing up unsealed management packs.'
        Try {
            $UnsealedmpWriter = new-object Microsoft.EnterpriseManagement.Configuration.IO.ManagementPackXmlWriter($UnsealedBackupDir)
        } Catch {
            Write-Error "Unable to create a ManagementPackXmlWriter object for location: $UnsealedBackupDir`."
        }

        if ($arrMPs.count -lt 1)
        {
            Write-Error "No management packs are found in the management group $MGName."
        } else {
            Write-Verbose "$($arrMPs.count) management packs found in the management group $MGName."
        }

        Foreach ($MP in $arrMPs)
        {

            If ($MP.Sealed)
            {
                Write-Verbose "Backing up sealed MP: $($MP.Name)"
                $mpWriter = $SealedmpWriter
            } else {
                Write-Verbose "Backing up unsealed MP: $($MP.Name)"
                $mpWriter = $UnsealedmpWriter
            }
            Try {
                If ($mpWriter)
                {
                    $mpWriter.WriteManagementPack($MP) | Out-Null
                }
            } Catch {
                Write-Error "Unable to export managment pack $($MP.Name)"
            }
        }
    } else {
        Write-Error "Invalid Backup Location specified`: $BackupLocation"
    }

    #Delete old backup only if this backup is considered successful.
    if ($error.count -eq 0)
    {
        Write-Verbose 'MP backup considered successful, deleting old backups now'
        $Result = $true
        $ChildItems += Get-ChildItem $BackupLocation | Where-Object {$_.PSIsContainer -eq $true}
        Foreach ($item in $ChildItems)
        {
            $fullPath = $item.FullName
            if ($item.CreationTime -le $date.adddays(-$RetentionDays))
            {
                Write-Verbose "Deleting $item"
                Remove-Item -Path $fullPath -Recurse -Force -Confirm:$false
            }
        }
    } else {
        Write-Error 'Error occurred during backup process.'
        $Result= $false
    }
    $Result
}

Function Approve-OMManualAgents
{
<#
 .Synopsis
  Approve manually installed OpsMgr agents that meet the naming convention
 
 .Description
  Approve manually installed OpsMgr agents that meet the naming convention using OpsMgr SDK
 
 .Parameter -SDKConnection
  OpsMgr SDK Connection object (SMA connection or hash table).
 
 .Parameter -SDK
  Management Server name
 
 .Parameter -UserName
  Alternative user name to connect to the management group (optional).
 
 .Parameter -Password
  Alternative password to connect to the management group (optional).
 
 .Parameter -AgentNameRegex
  Agent Name regular expression.
 
 .Parameter -AgentDomainRegex
  Agent Domain name regular expression.
 
 .Parameter -MaxToApprove
  Maximum number of manually installed agent to approve. the default value is 1 if it's not specified
 
 .Example
  # Connect to OpsMgr management group via management server "OpsMgrMS01" using alternative credentials and then approve manually installed agents with the following parameters:
  Agent Name Regular Expression: "^server\d{3}$"
  Agent Domain Regular Expression: "YourCompany.com"
  Maximum number of agents to approve: 50
  $Password = ConvertTo-SecureString -AsPlainText "password1234" -force
  Approve-OMManualAgents -SDK "OpsMgrMS01" -Username "domain\SCOM.Admin" -Password $Password -AgentNameRegex "^server\d{3}$" -AgentDomainRegex "YourCompany.com" -MaxToApprove 50
 
  .Example
  # Connect to OpsMgr management group using the SMA connection "OpsMgrSDK_TYANG" and then approve manually installed agent "SERVER01":
  $SDKCOnnection = Get-AutomationConnection "OpsMgrSDK_TYANG"
  Approve-OMManualAgents -SDKConnection $SDKConnection -AgentNameRegex "^server01$"
#>

    [CmdletBinding()]
    PARAM (
        [Parameter(ParameterSetName='SMAConnection',Mandatory=$true,HelpMessage='Please specify the SMA Connection object')][Alias('Connection','c')][Object]$SDKConnection,
        [Parameter(ParameterSetName='IndividualParameter',Mandatory=$true,HelpMessage='Please enter the Management Server name')][Alias('DAS','Server','s')][String]$SDK,
        [Parameter(ParameterSetName='IndividualParameter',Mandatory=$false,HelpMessage='Please enter the user name to connect to the OpsMgr management group')][Alias('u')][String]$Username = $null,
        [Parameter(ParameterSetName='IndividualParameter',Mandatory=$false,HelpMessage='Please enter the password to connect to the OpsMgr management group')][Alias('p')][SecureString]$Password = $null,
        [Parameter(Mandatory=$true,HelpMessage='Please enter agent name regular expression')][String]$AgentNameRegex,
        [Parameter(Mandatory=$false,HelpMessage='Please ente agent domain regular expression')][String]$AgentDomainRegex = $NULL,
        [Parameter(Mandatory=$false,HelpMessage='Please enter maxinum number of agents to be approved')][Int]$MaxToApprove = 1
    )

    #Connect to MG
    If ($SDKConnection)
    {
        Write-Verbose "Connecting to Management Group via SDK $($SDKConnection.ComputerName)`..."
        $MG = Connect-OMManagementGroup -SDKConnection $SDKConnection
        $SDK = $SDKConnection.ComputerName
        $Username = $SDKConnection.Username
        $Password= ConvertTo-SecureString -AsPlainText $SDKConnection.Password -force
    } else {
        Write-Verbose "Connecting to Management Group via SDK $SDK`..."
        If ($Username -and $Password)
        {
            $MG = Connect-OMManagementGroup -SDK $SDK -UserName $Username -Password $Password
        } else {
            $MG = Connect-OMManagementGroup -SDK $SDK
        }
    }

    $Admin = $MG.Administration
    $ApprovalList = New-object 'system.collections.generic.List[Microsoft.EnterpriseManagement.Administration.AgentPendingAction]'
    $arrApprovedComputers = @()
    $allPendingActions = $Admin.GetAgentPendingActions()
    Foreach ($item in $allPendingActions)
    {
        If ($item.AgentPendingActionType -eq 'ManualApproval')
        {
            $PreCount = $PreCount +1
            $AgentFQDN = $item.AgentName
            $AgentName = $($AgentFQDN.Split('.'))[0]
            $AgentDomain = $AgentFQDN.substring($AgentName.length+1, $($AgentFQDN.length-$agentName.length-1))
            if ($AgentName -imatch $AgentNameRegex -and $AgentDomain -imatch $AgentDomainRegex -and $ApprovalList.Count -lt $MaxToApprove)
            {
                #Add the agent to the approval list
                Write-Verbose "$AgentFQDN will be approved."
                $ApprovalList.Add($item)
                $arrApprovedComputers += $AgentFQDN
            }
        }
    }
    $ApprovedCount = $ApprovalList.count
    Write-Verbose "Total number of agents to be approved: $ApprovedCount"
    If ($ApprovedCount -gt 0)
    {
        Write-Verbose 'Approving manually installed agents'        
        $Admin.ApproveAgentPendingActions($ApprovalList)
    }
    Write-Output 'Done'
}

Function Add-OMManagementGroupToAgent
{
<#
 .Synopsis
  Configure an OpsMgr agent to report to a specific management group
 
 .Description
  Configure an OpsMgr agent to report to a specific management group using WinRM. If the management group have been successfully added, a boolean value $true will be returned, otherwise, a boolean value of $false is returned if any there are any errors occurred during the add process.
 
 .Parameter -AgentComputer
  Name of the agent computer
 
 .Parameter -UserName
  Alternative user name to connect to the agent computer (optional).
 
 .Parameter -Password
  Alternative password to connect to the agent computer (optional).
 
 .Parameter -WinRMPort
 The WinRM TCP port for configured on the agent computer. The default port of 5985 is used when not specified.
 
 .Parameter -ManagementServer
  The primary management server the agent computer is reporting to.
 
 .Parameter -ManagementGroupName
  Name of the management group the agent computer is reporting to.
 
 .Parameter -OpsMgrPort
  The TCP port that the agent computer is using to connect to the management group. The default port of 5723 is used when not specified.
 
  .Parameter -RemoveExistingMG
  Set this parameter to true to remove any existing management groups that have been configured on the agent computer
 
 .Example
  # Configure the agent computer "SERVER01" to report to the management serer "OPSMGR01" in management group "TYANG" and remove any existing management groups configured on the agent computer
 
  Add-OMManagementGroupToAgent -AgentComputer "SERVER01" -ManagementServer "OPSMGR01" -ManagementGroupName "TYANG" -RemoveExistingMG
 
  .Example
  # Connect to the agent computer "SERVER01" using alternative credentials and configure it to report to the management serer "OPSMGR01" in management group "TYANG" using WinRM port 1234
  $Password = ConvertTo-SecureString -AsPlainText "password1234" -force
  Add-OMManagementGroupToAgent -AgentComputer "SERVER01" -UserName "Domain\Admin" -Password $Password -ManagementServer "OPSMGR01" -ManagementGroupName "TYANG" -WinRMPort 1234
#>

    [CmdletBinding()]
    PARAM (
        [Parameter(Mandatory=$true,HelpMessage='Please enter the agent computer name')][Alias('Agent')][String]$AgentComputer,
        [Parameter(Mandatory=$false,HelpMessage='Please enter the user name to connect to the agent computer')][Alias('u')][String]$Username = $null,
        [Parameter(Mandatory=$false,HelpMessage='Please enter the password to connect to the agent computer')][Alias('p')][SecureString]$Password = $null,
        [Parameter(Mandatory=$false,HelpMessage='Please enter the WinRM port number configured on the agent computer')][Int]$WinRMPort = 5985,
        [Parameter(Mandatory=$true,HelpMessage='Please enter the Management Server name')][Alias('MS')][String]$ManagementServer,
        [Parameter(Mandatory=$true,HelpMessage='Please enter the management group name')][Alias('MG')][String]$ManagementGroupName,
        [Parameter(Mandatory=$false,HelpMessage='Please enter the port number for the OpsMgr agent communication')][Int]$OpsMgrPort = 5723,
        [Parameter(Mandatory=$false,HelpMessage='Remove existing management groups that are configured on the agent comptuer')][Boolean]$RemoveExistingMG = $false
    )
    #Create WinRM connection to the agent comptuer
    Write-Verbose "Trying to connect to $AgentComputer using WinRM"
    If ($Username -and $Password)
    {
        Write-Verbose "Alternative credential specified for the WinRM connection to $AgentComputer"
        $AgentCred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Username, $Password
    }
    Try {
        Write-Verbose "Creating WinRM session to $AgentComputer"
        if ($AgentCred)
        {
            $AgentSession = New-PSSession -ComputerName $AgentComputer -Credential $AgentCred -Port $WinRMPort -ErrorAction Stop
        } else {
            $AgentSession = New-PSSession -ComputerName $AgentComputer -Port $WinRMPort -ErrorAction Stop
        }
    } Catch {
        Write-Error "Unable to establish WinRM session to $AgentComputer"
    }
    Write-Verbose "Configuring $AgentComputer via WinRM"
    $AddResult = Invoke-Command -Session $AgentSession -ScriptBlock {
        Param([String]$ManagementServer, [String]$ManagementGroupName, [int]$OpsMgrPort, [Boolean]$RemoveExistingMG)
        Try {
            $objAgent = New-object -ComObject 'AgentConfigManager.MgmtSvcCfg'
        } Catch {
            Write-Error "Unable to create AgentConfigManager.MgmtSvcCfg object. Please make sure the appropriate version of OpsMgr 2012 agent is installed on $env:COMPUTERNAME"
        }

        #Get current configured management groups
        $arrCurrentMGs = $objAgent.GetManagementGroups()

        #Check if the agent is already configured to the management group
        $bAlreadyConfigured = $FALSE
        Write-Verbose "Checking if $env:ComputerName is already reporting to $ManagementGroupName"
        Foreach ($item in $arrCurrentMGs)
        {
            $ExistingMGName = $item.managementGroupName
            if ($ExistingMGName -ieq $ManagementGroupName)
            {
                Write-Warning "$env:ComputerName has already been configured to report to management group $ManagementGroupName"
                $bAlreadyConfigured = $true
            } else {
                if ($RemoveExistingMG)
                {
                    Write-Verbose "Removing Currently configured management group: $ExistingMGName"
                    $objAgent.RemoveManagementGroup($ExistingMGName)
                }
            }
        }

        If (!$bAlreadyConfigured)
        {
            Write-Verbose "$ManagementGroupName has not been configured on $env:comptername yet. Continuing configuration."
            If ($RemoveExistingMG -eq $FALSE)
            {
                If ($arrCurrentMGs.Count -ge 4)
                {
                    Write-Error "Unable to add additional MG to $env:COMPUTERNAME without removing any existing management groups. Currently there are $($arrCurrentMGs.count) management group configured, OpsMgr 2012 only supports up to 4 management groups for multihomed agents."
                    Exit
                }
            } else {
                Foreach ($item in $arrCurrentMGs)
                {
                    $ExistingMGName = $item.managementGroupName
                    Write-Verbose "Removing Currently configured management group: $ExistingMGName"
                    $objAgent.RemoveManagementGroup($ExistingMGName)
                }
            }
        
            #Add new MG
            Write-Verbose "Adding Management Group $ManagementGroupName to $env:ComputerName"
            $MGAddResult = $objAgent.AddManagementGroup($ManagementGroupName, $ManagementServer, $OpsMgrPort)
        }
        #Return result
        $error
    } -ArgumentList $ManagementServer, $ManagementGroupName, $OpsMgrPort, $RemoveExistingMG

    If ($AddResult)
    {
        Write-Error "Error occurred while configuring OpsMgr agent on $AgentComputer via WinRM."
        Write-Error $AddResult
        $Result = $false
    } else {
        Write-Verbose "$AgentComputer successfully configured"
        $Result = $true
    }
    #House clean
    Write-Verbose "Removing WinRM Session to $AgentComputer"
    Remove-PSSession $AgentSession
    $Result
}

Function Remove-OMManagementGroupFromAgent
{
<#
 .Synopsis
  Remove a management group configuration from an OpsMgr agent
 
 .Description
  Remove a management group configuration from an OpsMgr agent using WinRM. If the management group have been successfully deleted, a boolean value $true will be returned, otherwise, a boolean value of $false is returned if any there are any errors occurred during the deletion process.
 
 .Parameter -AgentComputer
  Name of the agent computer
 
 .Parameter -UserName
  Alternative user name to connect to the agent computer (optional).
 
 .Parameter -Password
  Alternative password to connect to the agent computer (optional).
 
 .Parameter -WinRMPort
 The WinRM TCP port for configured on the agent computer. The default port of 5985 is used when not specified.
 
 .Parameter -ManagementGroupName
  Name of the management group to be removed.
 
 .Example
  # Remove management group "TYANG" from OpsMgr agent on "SERVER01"
  Remove-OMManagementGroupFromAgent -AgentComputer "SERVER01" -ManagementGroupName "TYANG"
 
  .Example
  # Connect to the agent computer "SERVER01" using alternative credentials and remove management group "TYANG" using WinRM port 1234
  $Password = ConvertTo-SecureString -AsPlainText "password1234" -force
  Remove-OMManagementGroupFromAgent -AgentComputer "SERVER01" -UserName "Domain\Admin" -Password $Password -ManagementGroupName "TYANG" -WinRMPort 1234
#>

    [CmdletBinding()]
    PARAM (
        [Parameter(Mandatory=$true,HelpMessage='Please enter the agent computer name')][Alias('Agent')][String]$AgentComputer,
        [Parameter(Mandatory=$false,HelpMessage='Please enter the user name to connect to the agent computer')][Alias('u')][String]$Username = $null,
        [Parameter(Mandatory=$false,HelpMessage='Please enter the password to connect to the agent computer')][Alias('p')][SecureString]$Password = $null,
        [Parameter(Mandatory=$false,HelpMessage='Please enter the WinRM port number configured on the agent computer')][Int]$WinRMPort = 5985,
        [Parameter(Mandatory=$true,HelpMessage='Please enter the Management Server name')][Alias('MS')][String]$ManagementServer,
        [Parameter(Mandatory=$true,HelpMessage='Please enter the management group name')][Alias('MG')][String]$ManagementGroupName,
        [Parameter(Mandatory=$false,HelpMessage='Please enter the port number for the OpsMgr agent communication')][Int]$OpsMgrPort = 5723,
        [Parameter(Mandatory=$false,HelpMessage='Remove existing management groups that are configured on the agent comptuer')][Boolean]$RemoveExistingMG = $false
    )
    #Create WinRM connection to the agent comptuer
    Write-Verbose "Trying to connect to $AgentComputer using WinRM"
    If ($Username -and $Password)
    {
        Write-Verbose "Alternative credential specified for the WinRM connection to $AgentComputer"
        $AgentCred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Username, $Password
    }
    Try {
        Write-Verbose "Creating WinRM session to $AgentComputer"
        if ($AgentCred)
        {
            $AgentSession = New-PSSession -ComputerName $AgentComputer -Credential $AgentCred -Port $WinRMPort -ErrorAction Stop
        } else {
            $AgentSession = New-PSSession -ComputerName $AgentComputer -Port $WinRMPort -ErrorAction Stop
        }
    } Catch {
        Write-Error "Unable to establish WinRM session to $AgentComputer"
    }
    Write-Verbose "Configuring $AgentComputer via WinRM"
    $RemoveResult = Invoke-Command -Session $AgentSession -ScriptBlock {
        Param([String]$ManagementServer, [String]$ManagementGroupName, [int]$OpsMgrPort, [Boolean]$RemoveExistingMG)
        Try {
            $objAgent = New-object -ComObject 'AgentConfigManager.MgmtSvcCfg'
        } Catch {
            Write-Error "Unable to create AgentConfigManager.MgmtSvcCfg object. Please make sure the appropriate version of OpsMgr 2012 agent is installed on $env:COMPUTERNAME"
        }

        #Get current configured management groups
        $arrCurrentMGs = $objAgent.GetManagementGroups()

         Foreach ($item in $arrCurrentMGs)
        {
            $MGName = $item.managementGroupName
            if ($MGName -ieq $ManagementGroupName)
            {
                 Write-Verbose "Removing management group: $MGName"
                $objAgent.RemoveManagementGroup($MGName)
            } 
        }

        #Return result
        $error
    } -ArgumentList $ManagementGroupName

    If ($RemoveResult)
    {
        Write-Error "Error occurred while configuring OpsMgr agent on $AgentComputer via WinRM."
        Write-Error $RemoveResult
        $Result = $false
        
    } else {
        Write-Verbose "$AgentComputer successfully configured."
        $Result= $true
    }
    #House clean
    Write-Verbose "Removing WinRM Session to $AgentComputer"
    Remove-PSSession $AgentSession
    $Result
}

Function Get-OMManagementGroupDefaultSettings
{
<#
 .Synopsis
  Get OpsMgr management group default settings
 
 .Description
  Get OpsMgr management group default settings via OpsMgr SDK. A System.Collections.ArrayList is returned containing all management group default settings. Each setting in the arraylist is presented in a hashtable format.
 
 .Parameter -SDKConnection
  OpsMgr SDK Connection object (SMA connection or hash table).
 
 .Parameter -SDK
  Management Server name
 
 .Parameter -UserName
  Alternative user name to connect to the management group (optional).
 
 .Parameter -Password
  Alternative password to connect to the management group (optional).
 
 .Example
  # Connect to OpsMgr management group via management server "OpsMgrMS01" using alternative credentials and retrieve all the settings:
 
  $Password = ConvertTo-SecureString -AsPlainText "password1234" -force
  Get-OMManagementGroupDefaultSettings -SDK "OpsMgrMS01" -Username "domain\SCOM.Admin" -Password $Password
 
 .Example
  # Connect to OpsMgr management group using the SMA OpsMgrSDK connection "OpsMgrSDK_TYANG" and retrieve all the settings:
 
  $SDKConnection = Get-AutomationConnection -Name OpsMgrSDK_TYANG
  $MGSettings = Get-OMManagementGroupDefaultSettings -SDKConnection $SDKConnection
 
#>

    [CmdletBinding()]
    PARAM (
        [Parameter(ParameterSetName='SMAConnection',Mandatory=$true,HelpMessage='Please specify the SMA Connection object')][Alias('Connection','c')][Object]$SDKConnection,
        [Parameter(ParameterSetName='IndividualParameter',Mandatory=$true,HelpMessage='Please enter the Management Server name')][Alias('DAS','Server','s')][String]$SDK,
        [Parameter(ParameterSetName='IndividualParameter',Mandatory=$false,HelpMessage='Please enter the user name to connect to the OpsMgr management group')][Alias('u')][String]$Username = $null,
        [Parameter(ParameterSetName='IndividualParameter',Mandatory=$false,HelpMessage='Please enter the password to connect to the OpsMgr management group')][Alias('p')][SecureString]$Password = $null
    )

    #Connect to MG
    If ($SDKConnection)
    {
        Write-Verbose "Connecting to Management Group via SDK $($SDKConnection.ComputerName)`..."
        $MG = Connect-OMManagementGroup -SDKConnection $SDKConnection
        $SDK = $SDKConnection.ComputerName
        $Username = $SDKConnection.Username
        $Password= ConvertTo-SecureString -AsPlainText $SDKConnection.Password -force
    } else {
        Write-Verbose "Connecting to Management Group via SDK $SDK`..."
        If ($Username -and $Password)
        {
            $MG = Connect-OMManagementGroup -SDK $SDK -UserName $Username -Password $Password
        } else {
            $MG = Connect-OMManagementGroup -SDK $SDK
        }
    }


    $Admin = $MG.Administration
    $Settings = $Admin.Settings

    #Get Setting Types
    Write-Verbose 'Get all nested setting types'
    $arrRumtimeTypes = New-Object System.Collections.ArrayList
    $Assembly = [AppDomain]::CurrentDomain.GetAssemblies() |Where-Object { $_.FullName -eq 'Microsoft.EnterpriseManagement.OperationsManager, Version=7.0.5000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'}
    $SettingType = $assembly.definedtypes | Where-Object{$_.name -eq 'settings'}
    $TopLevelNestedTypes = $SettingType.GetNestedTypes()
    Foreach ($item in $TopLevelNestedTypes)
    {
        if ($item.DeclaredFields.count -gt 0)
        {
            [void]$arrRumtimeTypes.Add($item)
        }
        $NestedTypes = $item.GetNestedTypes()
        foreach ($NestedType in $NestedTypes)
        {
            [void]$arrRumtimeTypes.Add($NestedType)
        }
    }

    #Get Setting Values
    Write-Verbose 'Getting setting values'
    $arrSettingValues = New-Object System.Collections.ArrayList
    Foreach ($item in $arrRumtimeTypes)
    {
        Foreach ($field in $item.DeclaredFields)
        {
            $FieldSetting = $field.GetValue($field.Name)
            $SettingValue = $Settings.GetDefaultValue($FieldSetting)
            $hash = @{
                FieldName = $Field.Name
                Value = $SettingValue
                AllowOverride = $FieldSetting.AllowOverride
                SettingName = $item.Name
                SettingFullName = $item.FullName
            }
            $objSettingValue = New-object psobject -Property $hash
            [void]$arrSettingValues.Add($objSettingValue)
        }
    }
    Write-Verbose "Total number of Management Group default value found: $($arrSettingValues.count)."
    $arrSettingValues
}

Function Set-OMManagementGroupDefaultSetting
{
<#
 .Synopsis
  Set OpsMgr management group default settings
 
 .Description
  Set OpsMgr management group default settings via OpsMgr SDK. A boolean value $true will be returned if the setting has been successfully set, otherwise, a boolean value of $false is returned if any there are any errors occurred.
 
 .Parameter -SDKConnection
  OpsMgr SDK Connection object (SMA connection or hash table).
 
 .Parameter -SDK
  Management Server name
 
 .Parameter -UserName
  Alternative user name to connect to the management group (optional).
 
 .Parameter -Password
  Alternative password to connect to the management group (optional).
 
 .Parameter -SettingType
  Full name of the setting type (can be retrieved from Get-OMManagementGroupDefaultSettings).
 
 .Parameter -FieldName
  Field name of the setting type (can be retrieved from Get-OMManagementGroupDefaultSettings).
 
 .Parameter -Value
  Desired value that the field should be set to.
 
 .Example
  # Connect to OpsMgr management group via management server "OpsMgrMS01" using alternative credentials and set ProxyingEnabled default setting to TRUE:
  $Password = ConvertTo-SecureString -AsPlainText "password1234" -force
  Set-OMManagementGroupDefaultSetting -SDK "OpsMgrMS01" -Username "domain\SCOM.Admin" -Password $Password -SettingType Microsoft.EnterpriseManagement.Administration.Settings+HealthService -FieldName ProxyingEnabled -Value $TRUE
 
.Example
  # Connect to OpsMgr management group using the SMA OpsMgrSDK connection "OpsMgrSDK_TYANG" and set ProxyingEnabled default setting to TRUE:
  $SDKConnection = Get-AutomationConnection -Name OpsMgrSDK_TYANG
  Set-OMManagementGroupDefaultSetting -SDKConnection $SDKConnection -SettingType Microsoft.EnterpriseManagement.Administration.Settings+HealthService -FieldName ProxyingEnabled -Value $TRUE
#>

    [CmdletBinding()]
    PARAM (
        [Parameter(ParameterSetName='SMAConnection',Mandatory=$true,HelpMessage='Please specify the SMA Connection object')][Alias('Connection','c')][Object]$SDKConnection,
        [Parameter(ParameterSetName='IndividualParameter',Mandatory=$true,HelpMessage='Please enter the Management Server name')][Alias('DAS','Server','s')][String]$SDK,
        [Parameter(ParameterSetName='IndividualParameter',Mandatory=$false,HelpMessage='Please enter the user name to connect to the OpsMgr management group')][Alias('u')][String]$Username = $null,
        [Parameter(ParameterSetName='IndividualParameter',Mandatory=$false,HelpMessage='Please enter the password to connect to the OpsMgr management group')][Alias('p')][SecureString]$Password = $null,
        [Parameter(Mandatory=$true,HelpMessage='Please enter the Setting Type name')][Alias('Setting')][String]$SettingType,
        [Parameter(Mandatory=$true,HelpMessage='Please enter the Field name')][Alias('Field')][String]$FieldName,
        [Parameter(Mandatory=$true,HelpMessage='Please enter the new value for the field name')][Alias('v')]$Value
    )

    #Connect to MG
    If ($SDKConnection)
    {
        Write-Verbose "Connecting to Management Group via SDK $($SDKConnection.ComputerName)`..."
        $MG = Connect-OMManagementGroup -SDKConnection $SDKConnection
        $SDK = $SDKConnection.ComputerName
        $Username = $SDKConnection.Username
        $Password= ConvertTo-SecureString -AsPlainText $SDKConnection.Password -force
    } else {
        Write-Verbose "Connecting to Management Group via SDK $SDK`..."
        If ($Username -and $Password)
        {
            $MG = Connect-OMManagementGroup -SDK $SDK -UserName $Username -Password $Password
        } else {
            $MG = Connect-OMManagementGroup -SDK $SDK
        }
    }

    $Admin = $MG.Administration
    $Settings = $Admin.Settings

    #Get Setting Types
    $Assembly = [AppDomain]::CurrentDomain.GetAssemblies() |Where-Object { $_.FullName -eq 'Microsoft.EnterpriseManagement.OperationsManager, Version=7.0.5000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'}
    Write-Verbose "Getting $FieldName Field Type"
    $objSettingType = (New-object -TypeName $SettingType).GetType()
    #$objField = $objSettingType.GetDeclaredField($FieldName)
    $objField = $objSettingType.GetField($FieldName)
    $FieldSetting = $objField.GetValue($objField.Name)

     #Get current value - required to get value type
    $CurrentValue = $Settings.GetDefaultValue($FieldSetting)

    #Convert data type
    $ConvertedValue = $Value -as $CurrentValue.Gettype()
    If ($ConvertedValue -eq $null)
    {
        Write-Error "Unable to convert value $Value with type $($Value.gettype()) to type $($CurrentValue.Gettype())."
        $Result = $false
    } else {
        #Set default value
        Try {
            Write-Verbose "Setting default value of $FieldName to $Value"
            $Settings.SetDefaultValue($FieldSetting, $ConvertedValue)
            $Settings.ApplyChanges()
            $Result = $true
        } catch {
            Write-Error $_.Exception
            Write-Error "Unable to set the setting $SettingType`\$FieldName to $Value."
            $Result= $false
        }
    }
    $Result
}