I am trying to run a simple Powershell command let, which is listing all devices matching name criteria and in the next step is moving these devices to a select Azure group.
I tried with:
$result = Get-AzureADDevice -All $True -SearchString "LAP-BK" | ForEach-Object -Process {Add-AzureADGroupMember -ObjectId "25f94620-d850-4ec6-9476-050429d44926" -RefObjectId "$result.ObjectId"}
but that throwing errors. I also tried with
$result = Get-AzureADDevice -All $True -SearchString "LAP-BK" |Select-Object ObjectId
forEach ($item in $result)
{
Add-AzureADGroupMember -ObjectId "25f94620-d850-4ec6-9476-050429d44926" -RefObjectId "$item"
}
exit
The error are various, the last one I get was:
Error occurred while executing AddGroupMember Code: Request_BadRequest Message: Invalid object identifier ' #{ObjectId=debb95af-9h1f-49d6-ad84-8438f9c99b10}'. RequestId: 6df36830-7708-4f6b-b836-cd065f5f60b1
I tried to figure out the error from my end by running your script line by line, and I was able to find exactly where it was occurring:
Referring to Jamesyumnam article, I was able to successfully create and run the below script.
$groupName = "<groupName>"
Connect-AzureAD
$groupObject = Get-AzureADGroup -SearchString $groupName
$outcome = Get-AzureADDevice -SearchString "xxxxxx" | select-object objectID
try{
foreach ($item in $outcome)
{
$deviceObj = Get-AzureADDevice -SearchString $item.DeviceName
Add-AzureADGroupMember -ObjectId $groupObject.ObjectId -RefObjectId $item.ObjectId
}
}
catch {
Write-Host "Device not existed"
}
Executed in Azure PowerShell:
Member added in Azure Portal:
Note: It will be more helpful if you include try{} catch{} blocks in your code to find these kinds of blockers.
Related
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:
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:
I want to get the list of azure servers having auto-shutdown disabled on them, I have the below script but the issue with the script is that it gets the list of RG's under the Subscription GUID but repeats the output after every loop.
Import-AzureRmContext -Path "$PSScriptRoot\AzureProfile.json"
Select-AzureRmSubscription -SubscriptionId {subscriptionId}
[array]$ResourceGroupArray = Get-AzureRMVm | Select-Object -Property ResourceGroupName, Name, VmId
foreach ($resourceGroup in $ResourceGroupArray){
$targetResourceId = (Get-AzureRmVM -ResourceGroupName $resourcegroup.ResourceGroupName -Name $resourceGroup.Name).Id
$shutdownInformation = (Get-AzureRmResource -ResourceGroupName $resourcegroup.ResourceGroupName -ResourceType Microsoft.DevTestLab/schedules -Expandproperties).Properties
Write-Host "ID: " $targetResourceId
$shutdownInformation
The output for each VM is displayed in the following format,
What I want is simple, I want the VM name and its status of Auto-shutdown to be displayed on the screen so that its easy for me to find out which all VM have auto-shutdown currently disabled on them.
Any help related to this would be helpful.
You just need to get the microsoft.devtestlab/schedules resource ID using:
/subscriptions/{subscriptionId}/resourceGroups/{rgName}/providers/microsoft.devtestlab/schedules/shutdown-computevm-{vmName}
Then iterate over all your VMs using Get-AzVM, Get the microsoft.devtestlab/schedules resource using Get-AzResource, then output VM name and status into a table using Format-Table.
$subscriptionId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
Set-AzContext -SubscriptionId $subscriptionId
& {
foreach ($vm in Get-AzVM) {
try {
$shutdownResource = Get-AzResource `
-ResourceId "/subscriptions/$subscriptionId/resourceGroups/$($vm.ResourceGroupName)/providers/microsoft.devtestlab/schedules/shutdown-computevm-$($vm.Name)" `
-ErrorAction Stop
[PSCustomObject]#{
VMName = $vm.Name
ShutdownStatus = $shutdownResource.Properties.status
}
}
catch {
[PSCustomObject]#{
VMName = $vm.Name
ShutdownStatus = $_.Exception.Message
}
}
}
} | Format-Table -AutoSize
To set the context to the correct subscription, we can use Set-AzContext.
The above however is using the latest Az modules. You can do the same using the equivalent AzureRm modules.
$subscriptionId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
Set-AzureRmContext -SubscriptionId $subscriptionId
& {
foreach ($vm in Get-AzureRmVM) {
try {
$shutdownResource = Get-AzureRmResource `
-ResourceId "/subscriptions/$subscriptionId/resourceGroups/$($vm.ResourceGroupName)/providers/microsoft.devtestlab/schedules/shutdown-computevm-$($vm.Name)" `
-ErrorAction Stop
[PSCustomObject]#{
VMName = $vm.Name
ShutdownStatus = $shutdownResource.Properties.status
}
}
catch {
[PSCustomObject]#{
VMName = $vm.Name
ShutdownStatus = $_.Exception.Message
}
}
}
} | Format-Table -AutoSize
Although I do recommend moving to the Az module since support for AzureRm is ending December 2020. You can read the documentation for more information about this.
The above code should give you an output similar to the following
VMName ShutdownStatus
------ --------------
vm1 Enabled
vm2 Disabled
Update
The Call operator & is used here to run the for loop as a script block. You can read more about this in about_Script_Blocks.
Try something like this to get the auto-shutdown status of all VMs. Instead of trying to get the schedules inside the loop, get all the ones in the subscription and match them based on the VM's full resource Id.
[array]$VMArray = Get-AzureRMVm | Select-Object -Property ResourceGroupName, Name, VmId, Id
$ShutdownInformation = (Get-AzureRmResource -ResourceType Microsoft.DevTestLab/schedules -Expandproperties).Properties
foreach($vm in $VMArray) {
$ShutdownStatus = "Not Configured"
$Schedule = $ShutdownInformation | Where-Object { $_.targetResourceId -eq $vm.Id } | Select -First 1
if($Schedule -ne $null) {
$ShutdownStatus = $Schedule.status
}
Write-Host $vm.VmId $ShutdownStatus
}
Here is the code that I have written and modified several times, but still cannot get to work. Any help would be greatly appreciated. I keep receiving the following errors:
Get-AzureADUser : Cannot bind argument to parameter 'ObjectId' because it is null** and **New-AzureADUserAppRoleAssignment : Cannot bind argument to parameter 'ObjectId' because it is null.
# Assign the global values to the variables for the script.
$app_name = "App Name"
$app_role_name = "User"
$users = Get-Content 'Path\Users.txt'
$Credential=Get-StoredCredential -UserName #####
# Connect to Azure AD using Azure AD Powershell
Connect-AzureAD -Credential $Credential
# Get the user to assign, and the service principal for the app to assign to
foreach ($user in $users) {
$AADuser = Get-AzureADUser -ObjectId $user
$sp = Get-AzureADServicePrincipal -Filter "displayName eq '$app_name'"
$appRole = $sp.AppRoles | Where-Object { $_.DisplayName -eq $app_role_name }
# Assign the user to the app role
New-AzureADUserAppRoleAssignment -ObjectId $user.ObjectId -PrincipalId $user.ObjectId -ResourceId $sp.ObjectId -Id $appRole.Id
}'''
I'm trying to set a Tag on all virtual machines in my subscription but I keep getting errors when running the Runbook.
The error is the following:
Get-AzureRmVM : Cannot process command because of one or more missing mandatory parameters: ResourceGroupName. At line:30
Here is my Runbook:
$azureConnection = Get-AutomationConnection -Name 'AzureRunAsConnection'
#Authenticate
try {
Clear-Variable -Name params -Force -ErrorAction Ignore
$params = #{
ServicePrincipal = $true
Tenant = $azureConnection.TenantID
ApplicationId = $azureConnection.ApplicationID
CertificateThumbprint = $azureConnection.CertificateThumbprint
}
$null = Add-AzureRmAccount #params
}
catch {
$errorMessage = $_
Throw "Unable to authenticate with error: $errorMessage"
}
# Discovery of all Azure VM's in the current subscription.
$azurevms = Get-AzureRmVM | Select-Object -ExpandProperty Name
Write-Host "Discovering Azure VM's in the following subscription $SubscriptionID Please hold...."
Write-Host "The following VM's have been discovered in subscription $SubscriptionID"
$azurevms
foreach ($azurevm in $azurevms) {
Write-Host "Checking for tag $vmtagname on $azurevm"
$tagRGname = Get-AzureRmVM -Name $azurevm | Select-Object -ExpandProperty ResourceGroupName
$tags = (Get-AzureRmResource -ResourceGroupName $tagRGname -Name $azurevm).Tags
If ($tags.UpdateWindow){
Write-Host "$azurevm already has the tag $vmtagname."
}
else
{
Write-Host "Creating Tag $vmtagname and Value $tagvalue for $azurevm"
$tags.Add($vmtagname,$tagvalue)
Set-AzureRmResource -ResourceGroupName $tagRGname -ResourceName $azurevm -ResourceType Microsoft.Compute/virtualMachines -Tag $tags -Force `
}
}
Write-Host "All tagging is done"
I tried importing the right modules but this doesn't seem to affect the outcome.
Running the same commands in Cloud Shell does work correctly.
I can reproduce your issue, the error was caused by this part Get-AzureRmVM -Name $azurevm, when running this command, the -ResourceGroupName is needed.
You need to use the Az command Get-AzVM -Name $azurevm, it will work.
Running the same commands in Cloud Shell does work correctly.
In Cloud shell, azure essentially uses the new Az module to run your command, you can understand it runs the Enable-AzureRmAlias before the command, you could check that via debug mode.
Get-AzureRmVM -Name joyWindowsVM -debug
To solve your issue completely, I recommend you to use the new Az module, because the AzureRM module was deprecated and will not be updated.
Please follow the steps below.
1.Navigate to your automation account in the portal -> Modules, check if you have imported the modules Az.Accounts, Az.Compute, Az.Resources, if not, go to Browse Gallery -> search and import them.
2.After import successfully, change your script to the one like below, then it should work fine.
$azureConnection = Get-AutomationConnection -Name 'AzureRunAsConnection'
#Authenticate
try {
Clear-Variable -Name params -Force -ErrorAction Ignore
$params = #{
ServicePrincipal = $true
Tenant = $azureConnection.TenantID
ApplicationId = $azureConnection.ApplicationID
CertificateThumbprint = $azureConnection.CertificateThumbprint
}
$null = Connect-AzAccount #params
}
catch {
$errorMessage = $_
Throw "Unable to authenticate with error: $errorMessage"
}
# Discovery of all Azure VM's in the current subscription.
$azurevms = Get-AzVM | Select-Object -ExpandProperty Name
Write-Host "Discovering Azure VM's in the following subscription $SubscriptionID Please hold...."
Write-Host "The following VM's have been discovered in subscription $SubscriptionID"
$azurevms
foreach ($azurevm in $azurevms) {
Write-Host "Checking for tag $vmtagname on $azurevm"
$tagRGname = Get-AzVM -Name $azurevm | Select-Object -ExpandProperty ResourceGroupName
$tags = (Get-AzResource -ResourceGroupName $tagRGname -Name $azurevm).Tags
If ($tags.UpdateWindow){
Write-Host "$azurevm already has the tag $vmtagname."
}
else
{
Write-Host "Creating Tag $vmtagname and Value $tagvalue for $azurevm"
$tags.Add($vmtagname,$tagvalue)
Set-AzResource -ResourceGroupName $tagRGname -ResourceName $azurevm -ResourceType Microsoft.Compute/virtualMachines -Tag $tags -Force `
}
}
Write-Host "All tagging is done"