Writing Powershell Pester Test to check output contains multiple values - azure

I'm trying to check the permissions for an app registration in Azure and running
(Get-AzRoleAssignment -ObjectId $objectId).RoleDefinitionName
It returns multiple values, e.g "Owner, Contributor, Reader, KeyVault Secret User" etc.
I'm trying to write a Pester test to ensure it has either two values, or one.
As an example, $objectId should contain "Contributor" and KeyVault Secret User, OR, "Owner". So the test is happy as long as it has 'Owner', or 'Contributor/KeyVault Secret User'. Just to note, the test should still pass if it has all 3.
I have the below so far but can't seem to get this working from what I've found online.
BeforeALL {
$objectId = "<App-Reg-Object-Id>"
$RoleDefName = Get-AzRoleAssignment -ObjectId $objectId
}
Describe "Permissions Role Definition Checks" {
It "Checked the App Reg and it has the correct permissions" {
if ($RoleDefName.RoleDefinitionName | Should -Contain 'Owner')
{
Write-Host "Owner permission successfully found"
}
else {
$RoleDefName.RoleDefinitionName | Should -Contain 'Contributor'|'User Access Administrator'
}
}
}
}
Any help would be greatly appreciated
EDIT
This is now working with the help of Mark Wraggs' comment! I had to move the logic to the left of the Should, with a ForEach for the multiple roles. Below is how I got this working.
Describe "Permissions Role Definition Checks" {
It "Checked the App Reg and it has the correct permissions" -ForEach 'User Access Administrator','Contributor' {
$RoleDefName.RoleDefinitionName -Contains 'Owner' -Or $RoleDefName.RoleDefinitionName -Contains $_ | Should -Be $true
}
}

For this assertion, you need to do:
$RoleDefName.RoleDefinitionName | Should -Contain 'Contributor','User Access Administrator'
But because your scenario is a bit complex (where you want to check for two different results) it might be better to move the logic to the left of the Should. For example:
$RoleDefName.RoleDefinitionName -Contains 'Owner' -Or $RoleDefName.RoleDefinitionName -Contains 'Contributor','User Access Administrator' | Should -Be $true

Related

Getting Subscription ID with Resource Group without setting az context

I have a tenant with multiple subscriptions.
When I first login using Connect-AzAccount, it shows a message "TenantId 'xxxxx-xxxxx-xxx-xxx' contains more than one active subscription. First one will be selected for further use. To select another subscription, use Set-AzContext."
But I want to be able to do Get-AzResourceGroup -name 'abcd'.
The problem is resource group abcd is not under the first selected subscription selected from the login command.
I want to progromatically Get-AzResourceGroup -Name "ResourcegroupName" to retrieve the subscriptionID without setting az context as it defeats the purpose.
tried to clear the context clear-azContext but that signs me out.
I want to progromatically Get-AzResourceGroup -Name "ResourcegroupName" to retrieve the subscriptionID without setting az context as it defeats the purpose.
After reproducing from my end, Using the below script I could able to achieve your requirement.
$ResourceGroupName = Read-Host "Enter the resource group name you are searching for"
Get-AzSubscription | ForEach-Object {
$subscriptionName = $_.Name
$subscriptionId = $_.SubscriptionId
Set-AzContext -SubscriptionId $subscriptionId
(Get-AzResourceGroup).ResourceGroupName | ForEach-Object {
If ($ResourceGroupName -eq $_) {
[PSCustomObject] #{
Subscription = $subscriptionName
SubscriptionId = $subscriptionId
ResourceGroup = $_
}
}
}
}
RESULTS:

How do I check whether a device is already in an Azure group (Powershell)

I'm trying to find a way to see whether an Azure-enrolled device is a member of an Azure group.
The functionality I am aiming for is:
Enter device Object ID
Get all the Azure AD groups
Get the target device using 'Get-AzureADDevice'
Loop through a collection of groups and check if each group contains the device
If the device isn't in a group, add the device to the group. Otherwise skip.
Here is a snippet of my code so far:
$DeviceOID = Read-Host "Enter device's Object ID "
#Get All Azure AD Groups
$AzureGroups = Get-AzureADGroup -All:$true| Sort DisplayName
$Collection = #("Group1", "Group2", "Group3")
$targetDevice = Get-AzureADDevice -ObjectId $DeviceOID
#loop through and add user to each group
foreach ($Item in $Collection)
{
$GroupOID = ($AzureGroups | Where {$_.DisplayName -eq $Item}).ObjectID
$GroupMembers = Get-AzureADGroupMember -ObjectId $GroupOID -All $true
if ($GroupMembers -contains $targetDevice) {
Write-Output "Device already in $Item"
} else {
Add-AzureADGroupMember -ObjectID $GroupOID -RefObjectID $DeviceOID
}
}
The problem I am running into is that although the device is indeed in all 3 groups, the script is not recognising this and is still trying to add the device into said groups:
Add-AzureADGroupMember : Error occurred while executing AddGroupMember
Code: Request_BadRequest
Message: One or more added object references already exist for the following modified properties: 'members'.
I tried to reproduce the same in my environment its work successfully.
When I tried to use your cmdlet, my device is added in azure group successfully as below.
I tried to check whether my device is already exists in azure group I am getting the same error as below.
To resolve this issue, try to remove sort display the term 'Sort' is not recognized as a name of a cmdlet, and I agree with the guiwhatsthat you need to add ($Group in Members.ObjectId -contains $targetDevice.ObjectId) in if statement as below.
$DeviceOID = Read-Host "Enter device's Object ID "
#Get All Azure AD Groups
$AzureGroups = Get-AzureADGroup -All:$true
$Collection = #("Group1", "Group2", "TestGroup")
$targetDevice = Get-AzureADDevice -ObjectId $DeviceOID
#loop through and add user to each group
foreach ($Item in $Collection)
{
$GroupOID = ($AzureGroups | Where {$_.DisplayName -eq $Item}).ObjectID
$GroupMembers = Get-AzureADGroupMember -ObjectId $GroupOID -All $true
if ($GroupMembers.ObjectId -contains $targetDevice.ObjectId) {
Write-Output "Device already in $Item"
} else {
Add-AzureADGroupMember -ObjectID $GroupOID -RefObjectID $DeviceOID
}
}
Output:

Graph API permissions not removed from system assigned Managed Identity

I successfully assigned and am able to use Graph API Permissions in a system assigned Managed Identity context. However, I wanted to amend the permission scope. Using
$sp = Get-AzureADServicePrincipal -ObjectId "31dd2948-d2ed-49e8-a47c-188b607a3cf1" # AzureAutomationTest
# $sp = Get-AzureADServicePrincipal -ObjectId "ff628842-99a2-4d9c-990b-c008e7942efd" # AzureAutomationProd
# Get all delegated permissions for the service principal
$spOAuth2PermissionsGrants = Get-AzureADOAuth2PermissionGrant -All $true | Where-Object { $_.clientId -eq $sp.ObjectId }
# Remove all delegated permissions
$spOAuth2PermissionsGrants | ForEach-Object {
Remove-AzureADOAuth2PermissionGrant -ObjectId $_.ObjectId
}
# Get all application permissions for the service principal
$spApplicationPermissions = Get-AzureADServiceAppRoleAssignedTo -ObjectId $sp.ObjectId -All $true | Where-Object { $_.PrincipalType -eq "ServicePrincipal" }
# Remove all delegated permissions
$spApplicationPermissions | ForEach-Object {
Remove-AzureADServiceAppRoleAssignment -ObjectId $_.PrincipalId -AppRoleAssignmentId $_.objectId
}
I'm able to visibly delete the permissions from the https://portal.azure.com/#blade/Microsoft_AAD_IAM/ManagedAppMenuBlade/Permissions menu. However, it's not taking effect and it still works in the background.
Any idea?
Thanks.

Get the certificate status of all Service Principals, like if the certificate is invalid, in Azure, and eventually what they are connected to in Azure

I have a lot of service principles that have not been maintained as well as they should have. They are used in different pipelines and god only knows what.
I am trying to figure out a way to get a list of the invalid service principles. I can get all service principles by using Get-AzADServicePrincipal, but that will only get me identifiable information, not certificate status.
It also does not seem like Azure Resource Graph is going to give me this information.
So i am wondering if there is a trick that i am not aware of to get this information.
edit:
After looking at the answer to akb, the first part of the script would be something like
$value = Get-AzADServicePrincipal
$principleWithOutdatedCertList = [System.Collections.ArrayList]#()
$principlesWithNoCerts = [System.Collections.ArrayList]#()
for($num=1;$num -le $value.Count;$num++)
{
$cert = Get-AzADSpCredential -ObjectId $value[$num].Id
if ($cert.EndDate -lt (Get-Date)){
$principleWithOutdatedCertList.Add($value[$num].Id)
Write-Output $value[$num].Id
}
if($null -eq $cert)
{
$principlesWithNoCerts.Add($value[$num].Id)
}
}
Now it is only to connect those service principles to their resource that is needed :)
This script will provide info whether the Service Prinicpal has certs or not
$value = Get-AzADServicePrincipal
$date = Get-Date -Format d
for($num=0;$num -le $value.Count;$num++)
{
echo $value[$num].Id
$cert = Get-AzADSpCredential -ObjectId $value[$num].Id
if($cert -eq $null)
{
echo $value[$num].DisplayName "has no certs"
}
else
{
for($i=0;$i -le $cert.Count;$i++)
{
if($cert[$i].EndDate -gt $date)
{
echo $value[$num].DisplayName "has valid certs"
}
}
}
}

Is there a way to join a Windows 10 computer to Azure AD using PowerShell?

I want to join computers in my organization to Azure AD using a PowerShell script.
I tried using the New-AzureADDevice command
But in the example:
New-AzureADDevice -AccountEnabled $true -DisplayName "My new device" -AlternativeSecurityIds $altsecid -DeviceId $guid -DeviceOSType "OS/2" -DeviceOSVersion "9.3"
can someone explain where parameter AlternativeSecurityIds comes from?
AlternativeSecurityId which consists of three elements whereby only two would be needed for devices.
Reference : https://learn.microsoft.com/en-us/graph/api/resources/alternativesecurityid?view=graph-rest-1.0
AlternativeSecurityIds : {class AlternativeSecurityId {
IdentityProvider:
Key: System.Byte[]
Type: 2
}
}
Key itself is of type described here
X509:[thumbprint]+[publickeyhash]
Type determines the purpose of the key (eg Bitlocker, Windows Hello,Recoverykeys)
$key = [System.Text.Encoding]::Unicode.GetBytes("X509:<SHA1-TP-PUBKEY><Thumbprint>")
$altsecids = New-Object -TypeName PSObject -Property #{
#'IdentityProvider' = 'null'
'Key' = $key
'Type' = "2" }
New-AzureADDevice -AccountEnabled $true -DisplayName '<NAME>' -DeviceOSType 'OS/2' -DeviceOSVersion '9.3' -AlternativeSecurityIds $altsecids -DeviceId (New-Guid)
This is mostly used for internal use and my understanding you will not able to achieve your requirement.
Currently, there is no powershell script/commandlet that can auto join with AAD
There is already an existing Uservoice for the same.
The other option would be able to make use of :
Group Policy , OOBE, bulk enrollment and Autopilot

Resources