InActive-Owners.ps1
Function InActive-Owners { [CmdletBinding()] param ( [Parameter(ParameterSetName = 'One')]$Owner_TagKey <#= 'iicsSubscriptionOwner'#>, [Parameter(ParameterSetName = 'One')][switch]$SubscriptionTags, $SubscriptionName, [switch]$SecurityGroup, [switch]$AppReg, $UPN # [Parameter(ParameterSetName = 'Two')]$mailaddress ) <# .SYNOPSIS Get DISABLED resource owners details from App reg, Security Group and subscription scoped Tags. .DESCRIPTION Get list of DISABLED / InActive owners from Azure Security Group, Azure App Registration, And any Owner level Tags (limited to subscription scope.) .PARAMETER SecurityGroup Switch used to run thru all the security groups within the tenanat. No support for explicit SGs at this point. .PARAMETER AppReg Switch used to run thru all the Application Registrations within the tenanat. No support for explicit App registrations at this point. .PARAMETER SubscriptionTags Switch used in combination with Owner_TagKey. For more details look at examples. .PARAMETER Owner_TagKey Paramater that need to pass while used with SubscriptionTags. It includes the value of Tag name which holds subscription owners information. .PARAMETER UPN Parameter used for single UPN or user status check. Pass email address of user for which you need status. .EXAMPLE PS> $data = InActive-Owners -SecurityGroup $data | format-Table $data | Export-Csv -Path 'DisabledOwners.csv' -NoTypeInformation -Force .EXAMPLE PS> $data = InActive-Owners -SubscriptionTags -Owner_TagKey '<TagName>' $data | format-Table $data | Export-Csv -Path 'DisabledOwners.csv' -NoTypeInformation -Force .EXAMPLE PS> $data = InActive-Owners -AppReg $data | format-Table $data | Export-Csv -Path 'DisabledOwners.csv' -NoTypeInformation -Force .EXAMPLE PS> InActive-Owners -UPN <UserEmailAddress> .LINK Other packages: https://www.powershellgallery.com/packages?q=aammir #> $t1 = @' Designed and managed by ___ _ / _ \ (_) / /_\ \ __ _ _ __ ___ _ __ ___ _ _ __ | _ |/ _` | '_ ` _ \| '_ ` _ \| | '__| | | | | (_| | | | | | | | | | | | | | \_| |_/\__,_|_| |_| |_|_| |_| |_|_|_| Contact : aammir.mirza@hotmail.com '@ $t2 = @' +------------------+-----------------------------------------------------------------+----------------------------------------------+ | Switch | Usage | Example | +------------------+-----------------------------------------------------------------+----------------------------------------------+ | SecurityGroup | With this switch you can run accross all the | | | | SGs within AzureAD for which you (identity | $data = InActive-Owners -SecurityGroup | | | running functions) have access. | | +------------------+-----------------------------------------------------------------+----------------------------------------------+ | SubscriptionTags | With this switch you can run for subscription scope | $data = InActive-Owners -SubscriptionTags | | | Tags (service tags), having owner email address. | -Owner_TagKey '<TagName>' | | | You need to specify the Tag key. | | +------------------+-----------------------------------------------------------------+----------------------------------------------+ | AppReg | With this switch you can run for all Azure App Registrations to | $data = InActive-Owners -AppReg | | | verify the owners and If they are inActive. | | +------------------+-----------------------------------------------------------------+----------------------------------------------+ | UPN | With this switch you can run for individual UPN/ID to | InActive-Owners -UPN <UserEmailA> | | | verify the owners and If they are inActive. | | +------------------+-----------------------------------------------------------------+----------------------------------------------+ '@ Write-Verbose "`n$($t1)" Write-Verbose 'For more help on command and switches use -Verbose' Write-Verbose "Switches and there operations.`n$($t2)" $connect = Connect-MgGraph -AccessToken (Get-AzAccessToken -ResourceTypeName MSGraph).Token $url = 'https://graph.microsoft.com' $endpoint = "users/?`$select=" $graphversion = 'beta' $invalidUPN = @() $authHeader = @{ 'Content-Type' = 'application/json' 'Authorization' = 'Bearer ' + (Get-AzAccessToken -ResourceTypeName MSGraph).Token } if ($SubscriptionTags) { if ($SubscriptionName) { $subsName = Get-AzSubscription -SubscriptionName $SubscriptionName } else { $subsName = @() $subsName = (Get-AzSubscription <#| Select-Object -First 25#>) } foreach ($item in $subsName) { # | Where-Object -Property State -EQ 'Enabled')) { $context = Set-AzContext $item Write-Verbose "Execution for the subscription $($item.Name)" if ($($item.State) -eq 'Enabled') { Write-Verbose "Subscription State $($item.State)" # constructing Body $tags = Get-AzTag -ResourceId /subscriptions/$item Write-Verbose 'Parsing the TAGs now...' Write-Verbose "Checking subscription level tags for $($item.Name)" if ($tags) { foreach ($tagKey in $tags.Properties.TagsProperty.Keys) { $tagValue = $tags.Properties.TagsProperty[$tagKey] # Write-Host " | -- - $($tagKey):$($tagValue)" -ForegroundColor DarkYellow if ($tagKey -eq "$Owner_TagKey") { $iicsSubscriptionOwner = $tagValue } } if ($iicsSubscriptionOwner) { $filterOwner = "DisplayName, mail, accountEnabled&filter=mail eq '$($iicsSubscriptionOwner)'" $filterInactiveOwner = ' and accountEnabled eq false' $body = @{} $uri = "$url/$graphversion/$endpoint$filterOwner$filterInactiveOwner" $results = Invoke-MgGraphRequest ` -Uri $uri ` -Method GET ` -Body $body if ($results.value) { Write-Verbose " [INACTIVE] $($iicsSubscriptionOwner)" $invalidUPN += [PSCustomObject]@{ 'SubscriptionName' = $item.Name 'OwnerUPN' = $iicsSubscriptionOwner 'Status' = 'INACTIVE' } } else { Write-Verbose " [ACTIVE] $($iicsSubscriptionOwner)' Write-Verbose '$($item.Name) | $($iicsSubscriptionOwner)" } } # If block } } } } elseif ($SecurityGroup) { $invalidUPN = @() $sgCount = 0; # $groupId = '11e7b41d-d876-416c-abef-0ea1a23ab762' $graphversion = 'beta' $allGroupsEndpoint = 'groups?$filter=mailEnabled eq false' # Extracting all Security Groups $uriAllSg = "$url/$graphversion/$allGroupsEndpoint" $resultsAllSG = Invoke-MgGraphRequest ` -Uri $uriAllSg ` -Method GET $CloudSecurityGroups = $resultsAllSG.Value $UserNextLink = $resultsAllSG.'@odata.nextLink' while ($UserNextLink -ne $null) { $resultsAllSG = (Invoke-MgGraphRequest -Uri $UserNextLink -Method Get) $UserNextLink = $resultsAllSG.'@odata.nextLink' $CloudSecurityGroups += $resultsAllSG.value } Write-Verbose '-------------------------------' Write-Verbose "Total SG Count - $($CloudSecurityGroups.Count)" Write-Verbose '-------------------------------' foreach ($currentSG in $CloudSecurityGroups) { $sgCount = $sgCount + 1 Write-Verbose "$($sgCount) - $($currentSG.displayName)" $endpointSg = "groups/$($currentSG.id)/owners?`$select=imAddresses" $uriSg = "$url/$graphversion/$endpointSg" $SgOwners = Invoke-MgGraphRequest -Uri $uriSg -Method GET $count = ($SgOwners.Value.imAddresses).Count foreach ($currentItemName in $SgOwners.Value.imAddresses) { if ($currentItemName) { $filterOwner = "DisplayName, mail, accountEnabled&filter=mail eq '$($currentItemName)'" $filterInactiveOwner = ' and accountEnabled eq false' $body = @{} $uri = "$url/$graphversion/$endpoint$filterOwner$filterInactiveOwner" $results = Invoke-MgGraphRequest ` -Uri $uri ` -Method GET ` -Body $body if ($results.value) { $count = $count - 1 Write-Verbose " [INACTIVE] $($currentItemName)" $invalidUPN += [PSCustomObject]@{ 'SecurityGroupName' = $($currentSG.displayName) 'OwnerUPN' = $currentItemName 'Status' = 'INACTIVE' 'NumberOfActiveOwners' = $count } } else { Write-Verbose " [ACTIVE] $($currentItemName)" } } # If block } Write-Verbose "Active owners are - $($count)" } } elseif ($AppReg) { $invalidUPN = @() # Fetching all the App registrations $appRegistrations = Get-AzADApplication # | Select-Object -First 25 foreach ($appRegistration in $appRegistrations) { ('-' * 75) Write-Verbose " +++++ Running for $($appRegistration.DisplayName)" $owner = "https://graph.microsoft.com/v1.0/myorganization/applications/$($appRegistration.Id)/owners" $response2 = Invoke-RestMethod $owner -Method 'GET' -Headers $authHeader $count = ($response2.Value.userPrincipalName).Count Write-Verbose "+++ List of owners`n$($response2.Value.userPrincipalName)" foreach ($currentItemName in $response2.Value.userPrincipalName) { if ($currentItemName) { $filterOwner = "DisplayName, mail, accountEnabled&filter=mail eq '$($currentItemName)'" $filterInactiveOwner = ' and accountEnabled eq false' $body = @{} $uri = "$url/$graphversion/$endpoint$filterOwner$filterInactiveOwner" $results = Invoke-MgGraphRequest ` -Uri $uri ` -Method GET ` -Body $body if ($results.value) { $count = $count - 1 Write-Verbose " [INACTIVE] $($currentItemName)" $invalidUPN += [PSCustomObject]@{ 'AppRegName' = $($appRegistration.DisplayName) 'OwnerUPN' = $currentItemName 'Status' = 'INACTIVE' 'NumberOfActiveOwners' = $count } } else { Write-Verbose " [ACTIVE] $($currentItemName)" } } } # If block Write-Verbose "Active owners are - $($count)" } } elseif ($UPN) { $filterOwner = "DisplayName, mail, accountEnabled&filter=mail eq '$($UPN)'" $filterInactiveOwner = ' and accountEnabled eq false' $body = @{} $uri = "$url/$graphversion/$endpoint$filterOwner$filterInactiveOwner" $results = Invoke-MgGraphRequest ` -Uri $uri ` -Method GET ` -Body $body if ($results.value.accountEnabled -eq 'false') { Write-Verbose " [INACTIVE] $($UPN)" else { Write-Verbose " [ACTIVE] $($UPN)" } } } else { $t = @' +------------------+-----------------------------------------------------------------+----------------------------------------------+ | Switch | Usage | Example | +------------------+-----------------------------------------------------------------+----------------------------------------------+ | SecurityGroup | With this switch you can run accross all the | | | | SGs within AzureAD for which you (identity | $data = InActive-Owners -SecurityGroup | | | running functions) have access. | | +------------------+-----------------------------------------------------------------+----------------------------------------------+ | SubscriptionTags | With this switch you can run for subscription scope | $data = InActive-Owners -SubscriptionTags | | | Tags (service tags), having owner email address. | -Owner_TagKey '<TagName>' | | | You need to specify the Tag key. | | +------------------+-----------------------------------------------------------------+----------------------------------------------+ | AppReg | With this switch you can run for all Azure App Registrations to | $data = InActive-Owners -AppReg | | | verify the owners and If they are inActive. | | +------------------+-----------------------------------------------------------------+----------------------------------------------+ | UPN | With this switch you can run for individual UPN/ID to | InActive-Owners -UPN $mailaddress | | | verify the owners and If they are inActive. | | +------------------+-----------------------------------------------------------------+----------------------------------------------+ '@ Write-Warning "You must select one of the switch to perform the operation.`n$($t)" } # Function Output Write-Output $invalidUPN } |