Is there a better way to get users information and their manager for a specific MemberOf Group in Graph API Powershell - azure

Is there a better way to get users' information and their manager for a specific MemberOf Group in Graph API in Powershell? I have written below, it works but doesn't seem to be the best way to do this. I am new to this so please take it easy on me!
Ideally, I would like ALL fields from the Get-MgUser with the user's Manager and the specific MgUserMemberOf group I am searching for at the end of the CSV export, but not sure if it is possible.
if (Get-InstalledModule Microsoft.Graph) {
# Connect to MS Graph $appid = 'BLAH' $tenantid = 'BLAH' $secret = 'BLAH'
$body = #{
Grant_Type = "client_credentials"
Scope = "https://graph.microsoft.com/.default"
Client_Id = $appid
Client_Secret = $secret } $connection = Invoke-RestMethod `
-Uri https://login.microsoftonline.com/$tenantid/oauth2/v2.0/token `
-Method POST `
-Body $body $token = $connection.access_token Connect-MgGraph -AccessToken $token
### Comment out below to use the production version of Azure AD
Select-MgProfile -Name "beta"
$users = Get-MgUser -Filter "startsWith(DisplayName, 'Joe Bloggs')" foreach($Id in $users)
{
$MemberOf = Get-MgUserMemberOf -UserId $CurrentID | Where {$_.AdditionalProperties['displayName'] -like "*VIP*"} | Select id, #{E={$_.additionalProperties['displayName']}}
$UserManager = Get-MgUserManager -UserId $CurrentID | Select id, #{E={$_.additionalProperties['displayName']}}
$Result = "$($users.Id) , ""$($users.DisplayName)"", ""$($UserManager.'$_.additionalProperties[''displayName'']')"", ""$($MemberOf.'$_.additionalProperties[''displayName'']')"""
write-host $Result
Add-Content "C:\Temp\Result.csv" $Result
} }
Current Export
00000000-56fa-4638-9ff6-1dc85d3c9735 , "DISPLAY NAME", "MANAGER", "Member Of GROUP"

Your code is very confusing but I think what you're looking for is something similar to this:
if (Get-InstalledModule Microsoft.Graph) {
$params = #{
Uri = "https://login.microsoftonline.com/$tenantid/oauth2/v2.0/tokenMethod"
Method = 'POST'
Body = #{
Grant_Type = "client_credentials"
Scope = "https://graph.microsoft.com/.default"
Client_Id = $appid
Client_Secret = $secret
}
}
$connection = Invoke-RestMethod #params
Connect-MgGraph -AccessToken $connection.access_token
Select-MgProfile -Name "beta"
Get-MgUser -Filter "startsWith(DisplayName, 'Joe Bloggs')" | ForEach-Object {
[pscustomobject]#{
Id = $_.Id
DisplayName = $_.DisplayName
Manager = (Get-MgUserManager -UserId $_).additionalProperties['displayName']
MemberOf = (Get-MgUserMemberOf -UserId $_).Where{ $_.AdditionalProperties['displayName'] -like "*VIP*" }.additionalProperties['displayName']
}
} | Export-Csv "C:\Temp\Result.csv" -NoTypeInformation
}

Related

Add redirectUris for Azure application from PowerShell

This answer describes how to set a redirectUri to an Azure application using the Azure CLI:
az rest `
--method PATCH `
--uri 'https://graph.microsoft.com/v1.0/applications/{id}' `
--headers 'Content-Type=application/json' `
--body "{spa:{redirectUris:['http://localhost:3000']}}"
That request will overwrite the current list of redirect URIs. How can I add an item to the list instead?
We can use this below Powershell script to do the same using App Registration object id, client id and secrets .
$url = "http://localhost:4000"
$objectId = "<objectid>"
$clientId = "<clientID>"
$tenantValue ="<tenantID>"
$clientSecret ="<client secret value>"
$serviceAccountEmail = "yourusername.onmicrosoft.com"
$serviceAccountPassword = "your password"
$webServiceURL = $url
Write-Host "$webServiceURL"
Write-Host "Done creating the webServiceURL"
Write-Host "Convert password to Secure string"
$SecurePassword = ConvertTo-SecureString $serviceAccountPassword -AsPlainText -Force
Write-Host "Done converting password to Secure string"
$Credential = New-Object System.Management.Automation.PSCredential($serviceAccountEmail, $SecurePassword)
Write-Host "Logging in"
Login-AzAccount -Credential $Credential
$tid = (Get-AzTenant).Id
Write-Host "Getting token"
$tokenBody = #{
'tenant' = $tid
'client_id' = $clientId
'scope' = 'https://graph.microsoft.com/.default'
'client_secret' = $clientSecret
'grant_type' = 'client_credentials'
}
$Params = #{
'Uri' = "https://login.microsoftonline.com/$tid/oauth2/v2.0/token"
'Method' = 'Post'
'Body' = $tokenBody
'ContentType' = 'application/x-www-form-urlencoded'
}
$AuthResponse = Invoke-RestMethod #Params
$AuthResponse
$header = #{
'Content-Type' = 'application/json'
'Authorization' = "Bearer $($AuthResponse.access_token)"
}
$header
$redirectUris = (Invoke-RestMethod -Method Get -Uri "https://graph.microsoft.com/beta/applications/$objectId" -Headers $header).spa.redirectUris
if ($redirectUris -notcontains "$webServiceURL") {
$redirectUris += "$webServiceURL"
Write-Host "Adding $webServiceURL to redirect URIs";
}
$body = #{
'spa' = #{
'redirectUris' = $redirectUris
}
} | ConvertTo-Json
Invoke-RestMethod -Method Patch -Uri "https://graph.microsoft.com/beta/applications/$objectId" -Headers $header -Body $body
Here is the OUTPUT for Reference:-
You can fetch the current values with --method get, convert it to an ArrayList and then add your new value:
$appdata = az rest --method get --uri 'https://graph.microsoft.com/v1.0/applications/{id}' | ConvertFrom-Json
$uris = [System.Collections.ArrayList]$appdata.web.redirectUris
$uris.Add('abc')

Assigning Intune scope tags to Azure Azure AD group

I cannot figure this on out. I need a way to assign Endpoint Manager's Scope tags to an Azure AD group using Microsoft Graph and PowerShell.
Under the portal this is done under Endpoint Manager\Tenant Administration\Roles\Scope (Tags). Then clicking on the Tag and tgo to assignments and browse to Azure AD group.
Since its under Roles, I'm assuming it falls under the roleAssignment or roleScopeTag resource types?
I have thoroughly read all documentation for the REST api and I have also attempted to do this via Microsoft.Graph.Intune modules but still cannot find a suitable cmdlet that will do this. Am I missing something?
Here is the current code I have built following this document
FIRST let's assume I have the correct tag id and azure ad group object id.
$ScopeTagId = 2
$TargetGroupIds = #()
$TargetGroupIds += '687c08f1-e78f-4506-b4a6-dfe35a05d138'
$graphApiVersion = "beta"
$Resource = "deviceManagement/roleScopeTags"
$object = New-Object -TypeName PSObject
$object | Add-Member -MemberType NoteProperty -Name 'assignments' -Value #($TargetGroupIds)
$JSON = $object | ConvertTo-Json
$uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)/$ScopeTagId/assign"
Invoke-RestMethod -Method Post -Uri $uri -Headers $global:authToken -Body $JSON
No success. I then thought that since the create roleScopeTag API doesn't have an assignment property in the request body, this must be done using the update method, but that doesn't have it in there either. The only one I read was to use the assign action and in the documentation example it shows the roleScopeTagAutoAssignment URI, so I went down that rabbit hole:
$ScopeTagId = 2
$TargetGroupIds = #()
$TargetGroupIds += '687c08f1-e78f-4506-b4a6-dfe35a05d138'
$graphApiVersion = "beta"
$Resource = "deviceManagement/roleScopeTags"
$AutoTagObject = #()
foreach ($TargetGroupId in $TargetGroupIds) {
#Build custom object for assignment
$AssignmentProperties = "" | Select '#odata.type',id,target
$AssignmentProperties.'#odata.type' = '#microsoft.graph.roleScopeTagAutoAssignment'
$AssignmentProperties.id = $TargetGroupId
#Build custom object for target
$targetProperties = "" | Select "#odata.type",deviceAndAppManagementAssignmentFilterId,deviceAndAppManagementAssignmentFilterType
$targetProperties."#odata.type" = "microsoft.graph.deviceAndAppManagementAssignmentTarget"
$targetProperties.deviceAndAppManagementAssignmentFilterId = $TargetGroupId
$targetProperties.deviceAndAppManagementAssignmentFilterType = 'include'
#add target object to assignment
$AssignmentProperties.target = $targetProperties
$AutoTagObject += $AssignmentProperties
}
#build body object
$object = New-Object -TypeName PSObject
$object | Add-Member -MemberType NoteProperty -Name 'assignments' -Value #($AutoTagObject)
$JSON = $object | ConvertTo-Json
$uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)/$ScopeTagId/assign"
Invoke-RestMethod -Method Post -Uri $uri -Headers $global:authToken -Body $JSON
The error I get back is something like: "Property target in payload has a value that does not match schema.","innerError":{"date":"2022-01-27T16:28:34","request-id":"75626c4d-f09b-438e-8b0f-0b2928ac23ce","client-request-id":"75626c4d-f09b-438e-8b0f-0b2928ac23ce" which I assume is the odata.type object i'm calling "microsoft.graph.deviceAndAppManagementAssignmentTarget"
There is a second post method in the documentations via roledefinition URI which seems like an unnecessary step, but I tried that too with no success.
I do not know if any of this is correct. I understand the API calls for others pretty well and I have been able to successfully add Tags for Custom Roles and their assignments using graph; I just can't seem to find the right combination of URI and JSON body for scope tags themselves...if it even exists. :(
Any ideas, please share some code snippets if you can. THANKS!
I found the correct URI and request body
If can be generated like this:
$ScopeTagId = 2
$TargetGroupIds = #()
$TargetGroupIds += '687c08f1-e78f-4506-b4a6-dfe35a05d138'
$graphApiVersion = "beta"
$Resource = "deviceManagement/roleScopeTags"
$AutoTagObject = #()
#TEST $TargetGroupId = $TargetGroupIds[0]
foreach ($TargetGroupId in $TargetGroupIds) {
#Build custom object for assignment
$AssignmentProperties = "" | Select id,target
$AssignmentProperties.id = ($TargetGroupId + '_' + $ScopeTagId)
#Build custom object for target
$targetProperties = "" | Select "#odata.type",deviceAndAppManagementAssignmentFilterId,deviceAndAppManagementAssignmentFilterType,groupId
$targetProperties."#odata.type" = "microsoft.graph.groupAssignmentTarget"
$targetProperties.deviceAndAppManagementAssignmentFilterId = $null
$targetProperties.deviceAndAppManagementAssignmentFilterType = 'none'
$targetProperties.groupId = $TargetGroupId
#add target object to assignment
$AssignmentProperties.target = $targetProperties
$AutoTagObject += $AssignmentProperties
}
#build body object
$object = New-Object -TypeName PSObject
$object | Add-Member -MemberType NoteProperty -Name 'assignments' -Value #($AutoTagObject)
$JSON = $object | ConvertTo-Json -Depth 10
$uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)/$ScopeTagId/assign"
Invoke-RestMethod -Method Post -Uri $uri -Headers $global:authToken -Body $JSON -ErrorAction Stop
The Json request body would look like this:
{
"assignments": [
{
"id": "b25c80e3-78cc-4b7c-888e-fc50dcc6b582_2",
"target": {
"#odata.type": "microsoft.graph.groupAssignmentTarget",
"deviceAndAppManagementAssignmentFilterId": null,
"deviceAndAppManagementAssignmentFilterType": "none",
"groupId": "b25c80e3-78cc-4b7c-888e-fc50dcc6b582"
}
}
]
}
Nowhere is this documented...

ACTIVE DIRECTORY USERS AND GROUP INFO

I am looking to get all details of object id and display name present in my Azure active directory.
I know we can get display name using id using POWERSHELL
I am looking for a way to grab all details which are available.
Is there any python/powershell way to achieve this?
Here is how you can do it in PowerShell using the Microsoft Graph. You will need to setup an App Registration with at least Directory.Read.All for Microsoft Graph.
$TenantId = "xxxxxxxx-xxxx-xxxx-xxxx--xxxxxxxxxxxx"
$ClientId = "xxxxxxxx-xxxx-xxxx-xxxx--xxxxxxxxxxxx"
$ClientSecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
$logonURI = "login.microsoftonline.com" #Azure GCC-H: "login.microsoftonline.us"
$graphURI = "graph.microsoft.com" #Azure GCC-H: "graph.microsoft.us"
# Create a hashtable for the body, the data needed for the token request
# The variables used are explained above
$Body = #{
'tenant' = $TenantId
'client_id' = $ClientId
'scope' = "https://{0}/.default" -f $graphURI
'client_secret' = $ClientSecret
'grant_type' = 'client_credentials'
}
# Assemble a hashtable for splatting parameters, for readability
# The tenant id is used in the uri of the request as well as the body
$Params = #{
'Uri' = "https://{0}/$TenantId/oauth2/v2.0/token" -f $logonURI
'Method' = 'Post'
'Body' = $Body
'ContentType' = 'application/x-www-form-urlencoded'
}
$AuthResponse = Invoke-RestMethod #Params
$Headers = #{
'Authorization' = "Bearer $($AuthResponse.access_token)"
}
# 1. List all Users
$usrURI = "https://{0}/v1.0/users" -f $graphURI
$usrResult = Invoke-RestMethod -Uri $usrURI -Headers $Headers
$Users = $usrResult.value
while ($usrResult.'#odata.nextLink') {
Write-Host "Getting another page of 100 users..."
$usrResult = Invoke-RestMethod -Uri $usrResult.'#odata.nextLink' -Headers $Headers
$Users += $usrResult.value
}
foreach ($user in $Users)
{
$user
}
Once you know the displayname may be you can filter it as described in the Microsoft documentation for all other details.
example from documentaion.
PS C:\Windows\system32> Get-AzureADGroup -Filter "DisplayName eq 'The Display Name'"
Which gives all below details (copied from the Microsoft documentation link.)
https://learn.microsoft.com/en-ca/azure/active-directory/enterprise-users/groups-settings-v2-cmdlets
DeletionTimeStamp :
ObjectId : 31f1ff6c-d48c-4f8a-b2e1-abca7fd399df
ObjectType : Group
Description : Intune Device Administrators
DirSyncEnabled :
DisplayName : Intune Administrators
LastDirSyncTime :
Mail :
MailEnabled : False
MailNickName : 4dd067a0-6515-4f23-968a-cc2ffc2eff5c
OnPremisesSecurityIdentifier :
ProvisioningErrors : {}
ProxyAddresses : {}
SecurityEnabled : True

How to do az acr import with Az powershell?

If Az powershell does not have it, then a working code sample using the REST Api would be helpful.
This is the path I am going to pursue, but if someone has a working sample - please share.
It's impossible to import images to ACR through the Azure PowerShell, but the REST API exists. Take a look at the Import Image REST API.
So I managed to trigger the import using REST API. Here is my code (using a Service Principal to login):
function Get-AcrId($SubId, $RGName, $AcrName)
{
"/subscriptions/$SubId/resourceGroups/$RGName/providers/Microsoft.ContainerRegistry/registries/$ACRName"
}
function Get-AzureAuthenticationToken(
[Parameter(Mandatory)][String]$TenantID,
[Parameter(Mandatory)][String]$ClientID,
[Parameter(Mandatory)][String]$ClientSecret,
[Parameter(Mandatory)][String]$ResourceAppIDUri)
{
$tokenResponse = Invoke-RestMethod -Method Post -UseBasicParsing `
-Uri "https://login.windows.net/$TenantID/oauth2/token" `
-Body #{
resource = $ResourceAppIDUri
client_id = $ClientID
grant_type = 'client_credentials'
client_secret = $ClientSecret
} -ContentType 'application/x-www-form-urlencoded'
Write-Verbose "Access token type is $($tokenResponse.token_type), expires $($tokenResponse.expires_on)"
$tokenResponse.access_token
}
function Import-DockerImage(
[Parameter(Mandatory)]$SourceSubId,
[Parameter(Mandatory)]$SourceRGName,
[Parameter(Mandatory)]$SourceACRName,
[Parameter(Mandatory)]$TargetSubId,
[Parameter(Mandatory)]$TargetRGName,
[Parameter(Mandatory)]$TargetACRName,
[Parameter(Mandatory)]$ImageName,
[Parameter(Mandatory)]$ImageTag
)
{
$AzContext = Get-AzContext
if (!$AzContext)
{
throw "No Az context is found."
}
$TenantId = $AzContext.Tenant.Id
$ClientId = $AzContext.Account.Id
$ClientSecret = $AzContext.Account.ExtendedProperties.ServicePrincipalSecret
$token = Get-AzureAuthenticationToken -TenantID $TenantId -ClientID $ClientId -ClientSecret $ClientSecret -ResourceAppIDUri "https://management.core.windows.net/"
$url = "https://management.azure.com$(Get-AcrId $TargetSubId $TargetRGName $TargetACRName)/importImage?api-version=2019-05-01"
$body = #{
source = #{
resourceId = Get-AcrId $SourceSubId $SourceRGName $SourceACRName
sourceImage = "${ImageName}:$ImageTag"
}
targetTags = #(
"${ImageName}:$ImageTag"
)
mode = "NoForce"
} | ConvertTo-Json -Depth 99
$headers = #{
"Authorization" = "Bearer $token"
"Content-Type" = "application/json"
}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$r = Invoke-WebRequest $url -Method Post -Headers $headers -Body $body
$headers.Remove('Content-Type')
while ($r.StatusCode -eq 202)
{
$RetryAfter = $r.Headers.'Retry-After'
$Location = $r.Headers.Location
Start-Sleep -Seconds $RetryAfter
$r = Invoke-WebRequest $Location -Headers $headers
}

How to script External collaboration settings in Azure

Would like to be able to control two settings in Azure Active Directory user settings:
External collaboration settings > “Members can invite”
External collaboration settings > “Guests can invite”
As we already know, you can control just about everything in Azure with powershell, except these two things.
The internet, azure docs, and other resources, known to me, have been utilized to no real results.
Code: this is what we are looking to start.
Would like to say "Get-AzAADExternalCollaborationsSettings" then use the results to say "Set-AzAADExternalCollaborationsSettings".
AzAADUserSettings Picture
AFAIK, there is no built-in powershell command for the external collaboration settings, the two settings call the azure undisclosed api https://main.iam.ad.ext.azure.com/api/xxxx, the workaround I can just find is to invoke the api with powershell, here is a sample for you to refer, it calls a different api, but the logic should be similar. You can catch the requests of the two settings via fiddler and follow the sample to have a try.
Sample:http://www.lieben.nu/liebensraum/2018/04/how-to-grant-oauth2-permissions-to-an-azure-ad-application-using-powershell-unattended-silently/
Function Grant-OAuth2PermissionsToApp{
Param(
[Parameter(Mandatory=$true)]$Username, #global administrator username
[Parameter(Mandatory=$true)]$Password, #global administrator password
[Parameter(Mandatory=$true)]$azureAppId #application ID of the azure application you wish to admin-consent to
)
$secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ($Username, $secpasswd)
$res = login-azurermaccount -Credential $mycreds
$context = Get-AzureRmContext
$tenantId = $context.Tenant.Id
$refreshToken = #($context.TokenCache.ReadItems() | Where-Object {$_.tenantId -eq $tenantId -and $_.ExpiresOn -gt (Get-Date)})[0].RefreshToken
$body = "grant_type=refresh_token&refresh_token=$($refreshToken)&resource=74658136-14ec-4630-ad9b-26e160ff0fc6"
$apiToken = Invoke-RestMethod "https://login.windows.net/$tenantId/oauth2/token" -Method POST -Body $body -ContentType 'application/x-www-form-urlencoded'
$header = #{
'Authorization' = 'Bearer ' + $apiToken.access_token
'X-Requested-With'= 'XMLHttpRequest'
'x-ms-client-request-id'= [guid]::NewGuid()
'x-ms-correlation-id' = [guid]::NewGuid()}
$url = "https://main.iam.ad.ext.azure.com/api/RegisteredApplications/$azureAppId/Consent?onBehalfOfAll=true"
Invoke-RestMethod –Uri $url –Headers $header –Method POST -ErrorAction Stop
}
Through monitoring the webbrowser network reuest i was able to get the correct API URL https://main.iam.ad.ext.azure.com/api/Directories/B2BDirectoryProperties
This should be a Powershell command. Hopfully Microsoft does't break this API.
Here are some snippets of what i am using:
# Get API Token
$mycreds = Get-Credential
if($tenantId){
$res = login-azurermaccount -Credential $mycreds -TenantId $tenantId.ToLower()
}else{
$res = login-azurermaccount -Credential $mycreds
}
$context = Get-AzureRmContext
$tenantId = $context.Tenant.Id
$refreshToken = $context.TokenCache.ReadItems().RefreshToken
$body = "grant_type=refresh_token&refresh_token=$($refreshToken)&resource=74658136-14ec-4630-ad9b-26e160ff0fc6"
$apiToken = Invoke-RestMethod "https://login.windows.net/$tenantId/oauth2/token" -Method POST -Body $body -ContentType 'application/x-www-form-urlencoded'
# Get current settings
$header = #{
'X-Requested-With'= 'XMLHttpRequest'
"Origin"="https://portal.azure.com"
'Authorization' = 'Bearer ' + $apiToken.access_token
'x-ms-client-request-id'= [guid]::NewGuid()
}
$url = "https://main.iam.ad.ext.azure.com/api/Directories/B2BDirectoryProperties"
Invoke-WebRequest -Uri $url -Headers $header -ContentType "application/json" -ErrorAction Stop
# Change settings
$settings = #{
allowInvitations = $true
limitedAccessCanAddExternalUsers = $false
restrictDirectoryAccess = $true
usersCanAddExternalUsers = $false
}
$body = $settings | ConvertTo-Json
$header = #{
'X-Requested-With'= 'XMLHttpRequest'
"Origin"="https://portal.azure.com"
'Authorization' = 'Bearer ' + $apiToken.access_token
'x-ms-client-request-id'= [guid]::NewGuid()
}
$url = "https://main.iam.ad.ext.azure.com/api/Directories/B2BDirectoryProperties"
Invoke-WebRequest -Uri $url -Method "PUT" -Headers $header -ContentType "application/json" -Body $body
Thnx for pointing me in the right direction Joy.

Resources