Public/Get-SCOMRunAsProfilesAccounts.ps1
|
Function Get-SCOMRunAsProfilesAccounts { <# .DESCRIPTION Will output all RunAs accounts and any associated Security Profiles. .EXAMPLE Get-SCOMRunAsProfilesAccounts The above example will connect to localhost and output RunAs account and Seucrity Profile information. .EXAMPLE Get-SCOMRunAsProfilesAccounts -ManagementServer 'ms01.contoso.com' The above example will connect to the designated server and output RunAs account and Seucrity Profile information. .EXAMPLE Get-SCOMRunAsProfilesAccounts | Out-Gridview -Passthru The above example will display results in Gridview. Any selected rows can be passed through to the PowerShell Console for further review or manipulation. .INPUTS System.String .OUTPUTS Custom object .NOTES Author: Tyson Paul, derived from the works of Kevin Holman, Dirk Brinkman, Mihai (Sarbulescu?) Blog: https://monitoringguys.com/ History: 2020.02.25 - Revision of previous version (v1.0, Kevin Holman); improved efficiency, modified formatting. Ref: Kevin Holman: https://kevinholman.com/2017/07/27/document-your-scom-runas-account-and-profiles-script/ .FUNCTIONALITY This function works best when piped to Out-Gridview or exported to CSV. .LINK Get-SCOMRunAsAccountName #> Param( [string]$ManagementServer = 'LOCALHOST' ) ############# FUNCTIONS ################### Function Get-ClassfromInstance{ [CmdletBinding(DefaultParameterSetName='Parameter Set 1', SupportsShouldProcess=$true, PositionalBinding=$false, ConfirmImpact='Medium')] [OutputType([tinyClass])] Param ( $Instance ) $class = (Get-SCOMClass -Id $instance.LeastDerivedNonAbstractMonitoringClassId) $tmpClass = [tinyClass]::new() $tmpClass.Id = $class.Id $tmpClass.Name = $class.Name If ($class.DisplayName.Length -ne 0) { $tmpClass.DisplayName = $class.DisplayName } Return $tmpClass } ########### END FUNCTIONS ################# ########### BEGIN MAIN ################# # My custom object Class Account { [string]$RunAsAccountName = '' [string]$Domain = '' [string]$Username = '' [string]$AccountType = '' [string]$ProfileName = '' [string]$ProfileDisplayName = '' [string]$TargetClassID = '' [string]$TargetClassName = '' [string]$TargetClassDisplayName = '' [string]$TargetID = '' [string]$TargetName = '' [string]$TargetDisplayName = '' } Class tinyClass { [string]$Id = '' [string]$Name = '' [string]$DisplayName = '' } # Main array for account collection [System.Collections.ArrayList]$AccountDataArray = @() # Load Modules and Connect to SCOM . Import-SCOMPowerShellModule # Remove any existing/default mgmt group connection Get-SCOMManagementGroupConnection | Remove-SCOMManagementGroupConnection # Connect to designated mgmt server (explicit) $MGConnection = New-SCManagementGroupConnection -ComputerName $ManagementServer $MG = Connect-OMManagementGroup -SDK $ManagementServer # Load Assembly and define ManagementGroup Object $CoreDLL = 'Microsoft.EnterpriseManagement.Core' $null = [reflection.assembly]::LoadWithPartialName($CoreDLL) $EMG = New-Object -TypeName Microsoft.EnterpriseManagement.EnterpriseManagementGroup -ArgumentList ($ManagementServer) #Process HealthService based Action Accounts Section #======================================================= ForEach ($RunAsProfile in (Get-SCOMRunAsProfile)) { # Get Health Service array associated with the profile $HSRef = $MG.GetMonitoringSecureDataHealthServiceReferenceBySecureReferenceId($RunAsProfile.ID) ForEach ($HS in $HSRef) { $TargetName = (Get-SCOMClassInstance -Id $HS.HealthServiceId).Displayname $MonitoringData = $HS.GetMonitoringSecureData() $tempAccount = [Account]::new() $tempAccount.RunAsAccountName = $MonitoringData.Name $tempAccount.Domain = $MonitoringData.Domain $tempAccount.Username = $MonitoringData.UserName $tempAccount.AccountType = $MonitoringData.SecureDataType $tempAccount.ProfileName = $RunAsProfile.Name $tempAccount.TargetID = $HS.HealthServiceId.Guid.ToString() $tempAccount.TargetName = $TargetName $tempAccount.TargetDisplayName = '' $tmpClass = Get-ClassfromInstance -Instance (Get-SCOMClassInstance -Id $HS.HealthServiceId) $tempAccount.TargetClassId = $tmpClass.Id $tempAccount.TargetClassName = $tmpClass.Name $tempAccount.TargetClassDisplayName = $tmpClass.DisplayName If ($null -ne $RunAsProfile.DisplayName ) { $tempAccount.ProfileDisplayName = $RunAsProfile.DisplayName } #$AccountDataArray += $tempAccount $null = $AccountDataArray.Add($tempAccount) } } #======================================================= # End ForEach RunAsProfile # Process all RunAsAccounts targeted at other targets #======================================================= #Get all RunAsAccounts $colAccounts = $EMG.Security.GetSecureData() #Loop through each RunAs account ForEach ($account in $colAccounts) { $secStorId = $account.SecureStorageId $stringBuilder = New-Object -TypeName System.Text.StringBuilder $secStorId | ForEach-Object {$null = $stringBuilder.Append($_.ToString('X2'))} $MPCriteria = "Value='{0}'" -f $stringBuilder.ToString() $moc = New-Object -TypeName Microsoft.EnterpriseManagement.Configuration.ManagementPackOverrideCriteria -ArgumentList ($MPCriteria) $overrides = $EMG.Overrides.GetOverrides($moc) If ($overrides.Count -eq 0) { $tempAccount = [Account]::new() $tempAccount.RunAsAccountName = $account.Name $tempAccount.Domain = $account.Domain $tempAccount.Username = $account.UserName $tempAccount.AccountType = $account.SecureDataType $tempAccount.ProfileName = 'No Profile Assigned' $null = $AccountDataArray.Add($tempAccount) } # Customizations/overrides exist for the account, process them all. Else { ForEach ($override in $overrides) { # Every account will typically have these values $tempAccount = [Account]::new() $tempAccount.RunAsAccountName = $account.Name $tempAccount.Domain = $account.Domain $tempAccount.Username = $account.UserName $tempAccount.AccountType = $account.SecureDataType $tempAccount.TargetClassId = $override.Context.Id.Guid.ToString() $tmpClass = Get-SCClass -Id $tempAccount.TargetClassId $tempAccount.TargetClassName = $tmpClass.Name If ($null -ne $tmpClass.DisplayName) { $tempAccount.TargetClassDisplayName = $tmpClass.DisplayName } # If a ContextInstance (specific object) exists, add instance-specific data. If ($null -ne $override.ContextInstance) { $tempAccount.TargetID = $override.ContextInstance.Guid.ToString() $TargetClassInstance = Get-SCOMClassInstance -Id $tempAccount.TargetID $tempAccount.TargetName = $TargetClassInstance.Name If ($null -ne $TargetClassInstance.DisplayName) { $tempAccount.TargetDisplayName = $TargetClassInstance.DisplayName } } $secRef = $EMG.Security.GetSecureReference($override.SecureReference.Id) $tempAccount.ProfileName = $secRef.Name If ($null -ne $secRef.DisplayName) { $tempAccount.ProfileDisplayName = $secRef.DisplayName } # Add item to array $null = $AccountDataArray.Add($tempAccount) } } #End ForEach Override } #======================================================= # End ForEach account # Sort by RunAsAccountName. This is a nice touch for the user. Return ($AccountDataArray | Sort-Object -Property RunAsAccountName) } |