How can I get Azure container state from command line? - azure

I wonder how I can filter by the 'State' of the container group from the command line (Get-AzContainerGroup or az container list).
In azure portal this field is reported as 'Status'.
But I can't get it from the command line, it seems this field is not provisioned.
Get-AzContainerGroup | fl
ResourceGroupName : rg-foo
Id : /subscriptions/foo/resourceGroups/foo/providers/Microsoft.ContainerInstance/containerGroups/test-01
Name : test-01
Type : Microsoft.ContainerInstance/containerGroups
Location : westeurope
Tags : {}
ProvisioningState : Succeeded
Containers : {test-01}
ImageRegistryCredentials : {}
RestartPolicy : OnFailure
IpAddress : 20.82.63.136
DnsNameLabel :
Fqdn :
Ports : {80}
OsType : Linux
Volumes : {}
State :
Events : {}
Identity :
I've tried :
Get-AzContainerGroup | Where-Object {$_.State -eq "Succeeded"}
But as field seems was reported, it didn't work.

So, the Status column/property that you see on the Azure Portal actually translates to properties.instanceView.state for an Azure Container Instance.
It seems like this property isn't populated although present in the ouput of Get-AzContainerGroup | fl *. However, when the ResourceGroupName and Name parameters are passed along, you'd see it shows up!
Digging a little deeper, this is because the Get-AzContainerGroup cmdlet invokes the Container Groups - List REST API under the hood, that does not have the instanceView property in the response.
Whereas, Get-AzContainerGroup -ResourceGroupName <Resource-Group-Name> -Name <ContainerGroup-Name> calls the Container Groups - Get REST API that returns all the extended properties as well.
So, to work around this behavior, you can run the following snippet:
# List all container groups in the current subscription
# Equivalent to [Container Groups - List]
$AllContainerGroups = Get-AzContainerGroup
# Initialize an empty array to hold all container group objects with their extended properties
$AllContainerGroupsExtended = #()
foreach($ContainerGroup in $AllContainerGroups)
{
# Gets a specific container group
# Equivalent to [Container Groups - Get]
$ContainerGroupExtended = Get-AzContainerGroup -ResourceGroupName $ContainerGroup.Id.Split('/')[4] -Name $ContainerGroup.Name
$AllContainerGroupsExtended += $ContainerGroupExtended
}
# You can now filter the result as needed
$AllContainerGroupsExtended | Where-Object {$_.InstanceViewState -eq "Stopped"}

Related

Need to apply an if condition based on a check in Powershell

I am new to Powershell. I am actually getting the details of the azure data factory linked services but after get I need to use contains to check if the element exists. In python I would just check if string in a list but powershell not quite sure. Please check the code below.
$output = Get-AzDataFactoryV2LinkedService -ResourceGroupName $ResourceGroupName -DataFactoryName "xxxxxxxx" | Format-List
The output of the below is :
sample output given below
LinkedServiceName : abcdef
ResourceGroupName : ghijk
DataFactoryName : lmnopq
Properties : Microsoft.Azure.Management.DataFactory.Models.AzureDatabricksLinkedService
So now I try to do this:
if ($output.Properties -contains "Microsoft.Azure.Management.DataFactory.Models.AzureDatabricksLinkedService") {
Write-Output "test output"
}
But $output.Properties gives us the properties of that json.
I need to check if "Microsoft.Azure.Management.DataFactory.Models.AzureDatabricksLinkedService" exists in output variable and perform the required operations. Please help me on this.
The -contains operator requires a collection and an element. Here's a basic example of its proper use:
$collection = #(1,2,3,4)
$element1 = 5
$element2 = 3
if ($collection -contains $element1) {'yes'} else {'no'}
if ($collection -contains $element2) {'yes'} else {'no'}
What you've done is ask PowerShell to look in an object that isn't a collection for an element of type [string] and value equal to the name of that same object.
What you need to do is inspect this object:
$output.Properties | format-list *
Then once you figure out what needs to be present inside of it, create a new condition.
$output.Properties.something -eq 'some string value'
...assuming that your value is a string, for example.
I would recommend watching some beginner tutorials.

MS graph expanding and then filtering for multiple props does not apply filter

I'm trying to query graph, to get all the users in my tenant, which has access to a specific resource (i.e. my web application) and has a particular role
This is what I got so far:
https://graph.microsoft.com/v1.0/users?$select=id,givenName,surname,mail,preferredLanguage,externalUserState&$expand=appRoleAssignments($filter=resourceId eq ${resourceId} AND appRoleId eq ${appRole})
As you can see:
I get all my users
I expand my users with appRoleAssignments which should give me the application assignments for each user, and specific details for that assignment
I apply a filter to filter the object based on respectively resourceId AND appRoleId
The call works, but I'm returned every user in my tenant, which is definately not what I want - Preferably, I would like to get only the users returned, which has access to my resourceId and are assigned a particular appRoleId
It's not possible using Graph API.
For example , If I want to get the users based on a license SkuId , you can use the below API :
https://graph.microsoft.com/v1.0/users?$count=true&$filter=assignedLicenses/any(s:s/skuId eq b05e124f-xxxx-xxxx-xxxx-8xxxxxxx)
And it provides the output as the Assigned Licenses are a part of the same Odata Query .
But if you try the same thing for the App Role Assignments , It errors out with the following:
As the User Context and AppRoleAssignments Context lie in different Odata Contexts. So , when you are calling the query :
https://graph.microsoft.com/v1.0/users?$select=id,givenName,surname,mail,preferredLanguage,externalUserState&$expand=appRoleAssignments($filter=resourceId eq ${resourceId} AND appRoleId eq ${appRole})
The first part upto expand succeeds and returns the value but the second part i.e. the filter on the app role assignments doesn't work out which is why you are getting the list of all users.
As a solution ,you can use PowerShell script for the same by using conditional parameters:
Connect-AzureAD
$users=Get-AzureADUser
$Name=#()
foreach ($user in $users) {
$approle=Get-AzureADUserAppRoleAssignment -ObjectId $user.ObjectId
$resourceId= 'a19d7xx-xxxx-xxxx-xxx-c48c4d991411'
if ($approle.ResourceId -eq $resourceId){
$deviceprops = [ordered] #{
UserDisplayName = $approle.PrincipalDisplayName
}
$deviceobj = new-object -Type PSObject -Property $deviceprops
$Name += $deviceobj
}
}
$Name
Output:
Reference:
Get-AzureADUser and Get-AzureADUserAppRoleAssignment and Install AzureAD Module

Azure Powershell Positional Parameter error

I'm trying to do a deployment using powershell. Both parameter and template file are stored in blob storage, but I get the error below before it even tries to download the blobs.
New-AzResourceGroupDeployment : A positional parameter cannot be found that accepts argument 'newdeployment-878059'. At C:\Temp\New-Deployment\deploy-core.ps1:86 char:1
The code I use is below
$vnetRG = "rg-vnet"
$vpnRG = "rg-vpn"
$fwRG = "rg-fw"
$btnRG = "rg-bastion"
$loc = "west europe"
New-AzResourceGroupDeployment -Name = "newdeployment-$random"-ResourceGroupName "rg-vnet" `
-TemplateParameterFile "$PSScriptRoot\core.parameters.json" -TemplateUri = $templateFileUri `
-vpnResourceGroupName $rgRG -vpnResourceGroupName $vpnRG -fwResourceGroupName $fwRG -btnResourceGroupName $btnRG
I'm trying to deploy multiple resources to various resource groups in one subscription.
Thanks in advance :)
Here my comment as answer
In your code, you have added an = character between some of the parameter names and the actual value to use for that parameter.
In PowerShell you assign a value to a parameter with a space character between the two.
Also, there are parameters used that (according to the docs) don't exist for that cmdlet, like vpnResourceGroupName, fwResourceGroupName and btnResourceGroupName. To me, they sound like variables mistakenly added as parameter with the leading $ stripped off?
For cmdlets that can potentially use a large number of parameters, I'd recommend using Splatting, to keep the code clean and easy to maintain.
Something like:
$splatParams = #{
Name = "newdeployment-$random"
ResourceGroupName = "rg-vnet"
TemplateParameterFile = "$PSScriptRoot\core.parameters.json"
TemplateUri = $templateFileUri
}
New-AzResourceGroupDeployment #splatParams

Unexpected search result from Azure Search Graph Search-AzGraph vs Azure Resource Graph Explorer

I'm facing a weird behaviour (bug?) using the PowerShell command "Search-AzGraph".
When I use "Azure Resource Graph Explorer", I don't get this issue.
resourcecontainers
| where type =~ 'microsoft.resources/subscriptions/resourcegroups'
| join kind=leftouter (resources | project ResourceId=id, ResourceName=name, ResourceType=type, resourceGroup) on resourceGroup
(You can copy paste this KQL query directly on your Azure Resource Graph Explorer, it's to display all Azure resources with their Azure respective subscriptionId
With "Azure Resource Graph Explorer", after the "project" keyword to display the columns that I look for, I set "ResourceId" to display the Id of the resource. It works fine. I can see on the result that the column name changed.
But when using "Search-AzGraph", "ResourceId" values contain the value id from "resourcecontainers" instead of "resources".
If I remove the "ResourceId=", I got the same (correct) result as "Azure Resource Graph Explorer" but to access to it, I need to use the property "id1".
It's not a big deal but I wish to be able to use my own naming column.
Anyone got this experience or I miss something to get the result result on both cases?
Thanks
I finally found a workaround:
resourcecontainers
| where type =~ 'microsoft.resources/subscriptions/resourcegroups'
| join kind=leftouter (resources | project ResourceId=id, ResourceName=name, ResourceType=type, resourceGroup) on resourceGroup
| project ResourceGroupId=id, ResourceId, ResourceGroupName=name, ResourceName, tags
I added a "project" after my "join" to explicitly give a name to column "id" from "resourcecontainers", so the result don't mess up result (values) between "resourcecontainers" and "resource".
Here my full example of my PowerShell code, in case someone is interested:
$resources = Search-AzGraph -Subscription $subscriptionId -Query "resourcecontainers
| where type =~ 'microsoft.resources/subscriptions/resourcegroups'
| join kind=leftouter (resources | project ResourceId=id, ResourceName=name, ResourceType=type, resourceGroup) on resourceGroup
| project ResourceGroupId=id, ResourceId, ResourceGroupName=name, ResourceName, ResourceType, tags"
foreach ($resource in $resources) {
Write-Host "Resource Group Id: " $resource.ResourceGroupId
Write-Host " Resource Group Name: " $resource.ResourceGroupName
Write-Host " Resource Id: " $resource.ResourceId
Write-Host " Resource Name: " $resource.ResourceName
Write-Host " Resource Type: " $resource.ResourceType
}

Get Cosmosdb Container Collection items using powershell

Team, I had created new CosmosDB account in Azure portal with a container contains list of collection items. I am able to access Container details in power shell script.
How to list collection items or show specific collection item using partition key using power shell script
Power shell Script :
Get-AzResource -ResourceType "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers" -ApiVersion "2020-03-01" -ResourceGroupName "testRG" -Name "cosmosaccount1/database1/containercollection1"
You would need to use something like a thirdparty module for this. Azure Resource Manager doesnt support that, hence you need to talk to Cosmos DB directly.
https://github.com/PlagueHO/CosmosDB
The Cosmos DB repo has a set of examples to use Powershell: https://github.com/Azure/azure-cosmos-dotnet-v3/tree/master/Microsoft.Azure.Cosmos.Samples/Usage/PowerShellRestApi
Particularly to read Items: https://github.com/Azure/azure-cosmos-dotnet-v3/blob/master/Microsoft.Azure.Cosmos.Samples/Usage/PowerShellRestApi/PowerShellScripts/ReadItem.ps1
They are all using the REST API to do REST request, in this case, it is an authenticated GET to https://{databaseaccount}.documents.azure.com/dbs/{db-id}/colls/{coll-id}/docs/{id} (where databaseaccount is your account name, db-id is the id of your database, coll-id is the id of your collection/container, and id is your document id). It is also setting the x-ms-documentdb-partitionkey header for the partition key.
Like #4c74356b41 has indicated, you can use the CosmosDB module, which is now part of the official Az module.
Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force
You can see the available commands with Get-Commands:
Import-Module Az
Import-Module -Name CosmosDB
Get-Command -Module CosmosDB
Get all items in a collection
In order to get all entries inside a container, we use the Get-CosmosDbDocument command:
$subscription = "SubscriptionName"
$resourceGroupName = "ResourceGroupName"
$accountName = "AzureCosmosDBAccount"
$databaseName = "DatabaseName"
$cosmosContainer = "TargetCosmosDBContainer"
Set-AzContext $subscription
$backOffPolicy = New-CosmosDbBackoffPolicy -MaxRetries 5 -Method Additive -Delay 1000
$cosmosDbContext = New-CosmosDbContext -Account $accountName -Database
$databaseName -ResourceGroup $resourceGroupName -BackoffPolicy $backOffPolicy
$documentsPerRequest = 100
$continuationToken = $null
$documents = $null
do {
$responseHeader = $null
$getCosmosDbDocumentParameters = #{
Context = $cosmosDbContext
CollectionId = $cosmosContainer
MaxItemCount = $documentsPerRequest
ResponseHeader = ([ref] $responseHeader)
}
if ($continuationToken) {
$getCosmosDbDocumentParameters.ContinuationToken = $continuationToken
}
$documents += Get-CosmosDbDocument #getCosmosDbDocumentParameters
$continuationToken = Get-CosmosDbContinuationToken -ResponseHeader $responseHeader
} while (-not [System.String]::IsNullOrEmpty($continuationToken))
Note: There is no apparent limitation on the number of documents that can be retrieved with this command, but it stands to reason that the command will have the API limitation, and this is 4 MB (as documented here). The value here ($documentsPerRequest = 100) could prove to be either too big or too small, depending on the size of each document. I usually don't use this parameter, but I've mentioned it here in case someone needs it.
List specific collection item
To get a specific entry or group of entries from a container, we use the same Get-CosmosDbDocument command, in a slightly different way:
$query = "SELECT * FROM c WHERE c.property = 'propertyValue'"
$documents = Get-CosmosDbDocument -Context $cosmosDbContext -CollectionId $cosmosContainer -Query $query -QueryEnableCrossPartition $true
Note: For brevity I haven't went to the process of getting a continuation token, but if the query will return a result that is larger than 4 MB, then we will only receive the first part of the response. To make sure this does not happen we should add "Query" and "QueryEnableCrossPartition" in the $getCosmosDbDocumentParameters dictionary.

Resources