0

I am trying to create a script that locates a user, group, application, or service principal using an object id and application id (for application and service principal). I would like the script to be able to run with or without a switch parameter. I would like for it to be able to search all or be specific where to search. For example:

Search all: ./test.ps1 -ObjectId "xxxx-xxxx-xxxx-xxxxxx"

users and groups only: ./test.ps1 -ObjectId "xxxx-xxxx-xxxx-xxxxxx" -User -Group

applications only: ./test.ps1 -ObjectId "xxxx-xxxx-xxxx-xxxxxx" -App

If someone could check my work and provide feedback and/or suggestions, it would be very much appreciated! Thank you!

[CmdletBinding(DefaultParameterSetName='SearchAll')]
param(
    [Parameter(Mandatory=$true)]
    [ValidatePattern("^[a-z_0-9]{8}[-][a-z_0-9]{4}[-][a-z_0-9]{4}[-][a-z_0-9]{4}[-][a-z_0-9]{12}")]
    $objectID,
    
    [Parameter(ParameterSetName = 'Switches')]
    [switch]$User,
    [Parameter(ParameterSetName = 'Switches')]
    [switch]$Group,
    [Parameter(ParameterSetName = 'Switches')]
    [switch]$sp,
    [Parameter(ParameterSetName = 'Switches')]
    [switch]$App
)

if($PSCmdlet.ParameterSetName -eq 'Switches')
{
    if ($user.IsPresent) {
        Get-AzADUser -ObjectId $objectID | Select-Object Mail, DisplayName
        $found = $true }
    
    if ($group.IsPresent) {
        Get-AzADGroup -ObjectId $objectID | Select-Object DisplayName, Description, Id
        $found = $true }
   
    if ($app.IsPresent) { 
        Get-AzADApplication -ObjectId $objectID | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
        Get-AzADApplication -ApplicationId $objectID | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
        $found = $true }
   
    if ($sp.IsPresent) { 
        Get-AzADServicePrincipal -ObjectId $objectID | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
        Get-AzADServicePrincipal -ApplicationId $objectID | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
        $found = $true }
    if (-not $found) { Write-Warning "Not found." }
}

else{
    $user = Get-AzADUser -ObjectId $objectID
    if ($user)
    {
        $user | Format-List Mail, DisplayName
    }
    else
    {
        $group = Get-AzADGroup -ObjectId $objectID
        if ($group)
        {
            $group | Format-List DisplayName, Description, Id
        }
        else
        {
            $appO = Get-AzADApplication -ObjectId $objectID
            if ($appO)
            {
                Write-Host "ObjectID"
                $appO | Format-List ObjectType, DisplayName, Id, Type, ApplicationId
            }
            else
            {
                $appA = Get-AzADApplication -ApplicationId $objectID
                if ($appA)
                {
                    Write-Host "Application ID"
                    $appA | Format-List ObjectType, DisplayName, Id, Type, ApplicationId
                }
                else
                {
                    $spO = Get-AzADServicePrincipal -ObjectId $objectID
                    if ($spO)
                    {
                        $spO | Format-List ObjectType, DisplayName, Id, Type, ApplicationId
                    }
                    else
                    {
                        $spA = Get-AzADServicePrincipal -ApplicationId $objectID
                        if ($spA)
                        {
                            $spA | Format-List ObjectType, DisplayName, Id, Type, ApplicationId
                        }
                        else
                        {
                            Write-Warning "Object does not exist."
                        }
                    }
                }
            }
        }
    }
}

Also, the

if (-not $found) { Write-Warning "Not found." }

line does not seem to work. Any advice?

3
  • I put forward an answer re $found. I left some pointers for the code review of your question. But I think there is another forum for code review. Let me know, because I'd like to take some of the fluff out of the answer. Commented Sep 9, 2021 at 23:56
  • @Steven The OP would need to have the code working (i.e. including the line that does not seem to work) before posting on CR - otherwise it would not be on-topic Commented Sep 10, 2021 at 0:01
  • @SᴀᴍOnᴇᴌᴀ Thanks. We'll see how this goes. I just want to make sure the answer gets cleaned up in the end. Assuming it's worth it at all. Commented Sep 10, 2021 at 0:56

1 Answer 1

2

Looks like you are setting $found to $true regardless the outcome of Get-AzADUser or any of the other commands. Since you're doing so in each if/else script block an expression like -not $found will always come back false, therefore the warning will never be written.

The simple solution would be to assign the returned/found object to a variable, then test if the variable is populated in order to set $found. Then go ahead and output the variable as you would have before:

if ( $user ) {
    $AzADUser = Get-AzADUser -ObjectId $objectID
    If( $AzADUser ) { $found = $true }
    $AzADUser | Select-Object Mail, DisplayName
}

if ( $group ) {
    $AzADGroup = Get-AzADGroup -ObjectId $objectID    
    If( $AzADGroup ) { $found = $true }
    $AzADGroup | Select-Object DisplayName, Description, Id
}

if ( $app ) { 
    $AzADApplication =  @(Get-AzADApplication -ObjectId $objectID)
    $AzADApplication += Get-AzADApplication -ApplicationId $objectID
    If( $AzADApplication ) { $found = $true }
    $AzADApplication| Select-Object ObjectType, DisplayName, Id, Type, ApplicationId    
}

if ( $sp ) { 
    $AzADServicePrincipal =  @(Get-AzADServicePrincipal -ObjectId $objectID)
    $AzADServicePrincipal += Get-AzADServicePrincipal -ApplicationId $objectID
    If( $AzADServicePrincipal ) { $found = $true }
    $AzADServicePrincipal | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
}

if (-not $found) { Write-Warning "Not found." }

Note: You do not need to reference .IsPresent

Obviously you can repeat this for the different switch params.

However, this is a little wordy because you're using the same variable to represent several different types of objects potentially returned. Furthermore, you're returning different properties depending on the object type.

You could potentially improve this using a Switch statement:

Switch ([Boolean]$true) {
    $user {
        Get-AzADUser -ObjectId $objectID | Select-Object Mail, DisplayName
    }
    $group {
        Get-AzADGroup -ObjectId $objectID | Select-Object DisplayName, Description, Id        
    }
    $app {
        Get-AzADApplication -ObjectId $objectID | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
        Get-AzADApplication -ApplicationId $objectID | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
    }
    $sp {
        Get-AzADServicePrincipal -ObjectId $objectID | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
        Get-AzADServicePrincipal -ApplicationId $objectID | Select-Object ObjectType, DisplayName, Id, Type, ApplicationId
    }
    Default {
        Write-Warning "Not found."
    }
}

One advantage is that any matching script block will execute except for the default which will only run if no other block executes. In this case you do not need repetitive If statements or $found.

Even with a cleaner version using Switch, the code is still quite repetitive. I'd think there's a more generic way to query for an object who's type you may at first be unaware of. If this were an on-prem AD implementation I would use Get-ADObject then output differently depending on what type of object it returns. That would remove the need for switch parameters altogether. Perhaps you can use Get-AzureADObjectById from the Azure Active Directory PowerShell module to employ a similar strategy

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, Steven! If I use what you provided, would it be separated if statements for each parameter, or would it be nested if statements?
You can arrange similar to before with separate If blocks looking for each switch parameter. I updated the sample to include all the If statements. However I also added a switch based example and improved the alternate approach advice. At any rate if you are comfortable with the solution, please consider accepting the answer. Doing so will help others find and reference our work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.