0

I have a very simple script that is connecting to AzureAD and pulling Roles and Members of said roles within AD.

I can get it to run fine within powershell, however when i start to add Out-File or similar i obvioulsy need to call from a stored item, I add $Export to the foreach, it runs fine however when i preview it, it is missing the $Write-Host $ADRole.Displaname from the foreach.

## CONNECT AZURE AD ##
Connect-AzureAD

## Get Administrator Account Users 
$Export = ForEach ($ADRole in Get-AzureADDirectoryRole) {
    Write-Host $ADRole.DisplayName
    Get-AzureADDirectoryRoleMember -ObjectId $ADRole.objectID | Format-Table DisplayName,UserPrincipalName,UserType,ObjectId
}

$Export | Out-File -FilePath C:\Temp\Test.txt

As per my comment below i think the output of this doesnt work as efficient as it should as there is no specific way to filter by user etc, which ofcourse is a limitation with a .txt file so i think i need to make this output to a csv.

Upon initial output of CSV it would output all as 1 column and 1 line so not very functional, give the $ADRole.DisplayName is shown above the users i think this would be best to show inline for the CSV so it would output as follows.

$ADRole.DisplayName, $Member.DisplayName,$Member.UserPrincipalName,$Member.UserType,$Member.ObjectID

Although there are roles which have no users assigned to it, however those roles still need to show for any external audits?

What is the best way to achieve this?

5
  • Because...........Write-Host does just as the name implies. Writes to the host (console) and does nothing else. You want to use Write-Output to write to the pipeline. So, it's definitely outputting as it should. Commented Aug 5, 2021 at 0:23
  • 1
    Literally as I looked at it after posting, I simply removed Write-Host and well, as you mentioned fixed! Commented Aug 5, 2021 at 0:24
  • Yeah, using single/double-quotes by themselves without specifying a cmdlet, default to Write-Output, so that will work as well. Glad you got it figured out tho:) Commented Aug 5, 2021 at 0:26
  • 1
    Write-Host is typically the wrong tool to use, unless the intent is to write to the display only, bypassing the success output stream and with it the ability to send output to other commands, capture it in a variable, or redirect it to a file. To output a value, use it by itself; e.g., $value instead of Write-Host $value (or use Write-Output $value, though that is rarely needed); see this answer Commented Aug 5, 2021 at 0:48
  • Have made additional edits to the original post. Commented Aug 5, 2021 at 1:21

1 Answer 1

1

Similar to what Abraham and mklement0 pointed out in their comments in regards to Write-Host, something similar happens with Format-Table, it is intended to display your object on the console and should not be used to export the data.

Select the properties you need to export with Select-Object instead or loop through the object and cast a [pscustomobject].

$Export = ForEach ($ADRole in Get-AzureADDirectoryRole)
{
    Write-Host $ADRole.DisplayName
    $members = Get-AzureADDirectoryRoleMember -ObjectId $ADRole.objectID

    if(-not $members)
    {
        $ADRole | Select-Object @{n='ADRoleDisplayName';e={$_.DisplayName}},
                                @{n='MemberDisplayName';e={'No Members'}},
                                UserPrincipalName, UserType, ObjectId
        continue
    }

    $members | Select-Object @{n='ADRoleDisplayName';e={$ADRole.DisplayName}},
                             @{n='MemberDisplayName';e={$_.DisplayName}},
                             UserPrincipalName, UserType, ObjectId
}

$Export | Export-Csv C:\Temp\Test.txt -NoTypeInformation
  • For casting [pscustomobject] you can do something like this:
$Export = ForEach ($ADRole in Get-AzureADDirectoryRole)
{
    Write-Host $ADRole.DisplayName
    $members = Get-AzureADDirectoryRoleMember -ObjectId $ADRole.objectID
    
    if(-not $members)
    {
        [pscustomobject]@{
            ADRoleDisplayName = $ADRole.DisplayName
            MemberDisplayName = 'No Members'
            UserPrincipalName = ''
            UserType = ''
            ObjectId = ''
        }

        continue
    }

    foreach($member in $members)
    {
        [pscustomobject]@{
            ADRoleDisplayName = $ADRole.DisplayName
            MemberDisplayName = $member.DisplayName
            UserPrincipalName = $member.UserPrincipalName
            UserType = $member.UserType
            ObjectId = $member.ObjectId
        }
    }
}

$Export | Export-Csv C:\Temp\Test.txt -NoTypeInformation
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks mate, whilst this is all good and working (Appreciate it) the issue would now rely around rolls that have no members, soley from an audit perspective that it shows the role has no members.
@AndrewWaters if its related to this question Although there are roles which have no users assigned to it, however those roles still need to show for any external audits? not sure how can we decide that for you.
Yeah, for the purpose of clarity, for any audits we are required to show all roles with members or no members. Whilst i understand it is pointless to show them with no roles, for our auditors that want to see that there is nothing. Again it if i had it my way i wouldnt bother with showing them.
@AndrewWaters I see what you mean, for some roles, Get-AzureADDirectoryRoleMember -ObjectId $ADRole.objectID doesn't produce any output hence it doesn't get exported. I know how to fix that but I need to know if the code is throwing any errors.
No errors are shown, i am using the second method with the [pscustomobject]
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.