Authenticated with "Login-AzureRmAccount -ServicePrincipal" but no subscription is set? - azure

I've successfully created a self-signed certificate with application & service principle using the New-AzureRmADApplication and New-AzureRmADServicePrincipal cmdlets.
I can execute the login using this command after retrieving the certificate:
Login-AzureRmAccount -ServicePrincipal -CertificateThumbprint $cert.Thumbprint -TenantId $tenantID -ApplicationId $applicationID
However, the SubscriptionId/SubscriptionName attributes of this authentication display as blank:
Environment : AzureCloud
Account : ********************
TenantId : ********************
SubscriptionId :
SubscriptionName :
CurrentStorageAccount :
Subsquently, this command works!
$secret = Get-AzureKeyVaultSecret -VaultName $vaultName -Name $keyName
What is confusing to me is that I am able to retrieve a AzureKeyVaultSecret in my DEV subscription, but I do not understand how this cmdlet knows which of my subscriptions to use??? I intend to create the same vault in my PROD subscription, but first need to understand how this ServicePrincipal/Certificate authentication knows which subscription to pull from and/or how to manipulate it?
I can say that when I created the App/ServicePrincipal, I logged in specifying the "DEV" subscription like so:
$subscriptionName = "DEV"
$user = "user#company.com"
$password = "*****"
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential ($user, $securePassword)
Login-AzureRmAccount -Credential $credential -SubscriptionName $subscriptionName

Related

How do I connect to Azure through PowerShell Modules, using the Service principal of a Registered App?

I need to create a powershell script that queries Azure Resources.
What I have is an App Registration.
App Registrations give us the following information:
# --- APP REGISTRATION OUTPUT
# appId = "***** APP ID *******"
# displayName = "**** APP Name **** "
# password = "***** SECRET *******"
# tenant = "**** TENANT ID *****"
I need to use these credentials to now access Azure via PowerShell script.
I have tried the following:
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $ApplicationId, $SecuredPassword
Connect-AzAccount -ServicePrincipal -TenantId $TenantId -Credential $Credential
But I get an error:
… Account -ServicePrincipal -TenantId $TenantId -Credential $Credential
| ~~~~~~~~~~~
| Cannot bind argument to parameter 'Credential' because it is null.
I don't think what Im doing is abnormal. App Registrations give us the ability to allow Apps (PowerShell Apps!) to interact with a given tenant. Or am I mistaken?
I don't want the app to login every time using an account (i.e. To have a browser window open whenever the script runs).
What am I doing wrong?
You have missed converting your password into secure string. You could verify that in your $credential variable.
$ApplicationId = "0000-0000-0000-0000"
$Password = "000000000000000"
$TenantId = "0000-0000-000-000"
$subscriptionId = "0000-0000-0000-0000"
$SecuredPassword = ConvertTo-SecureString -AsPlainText $Password -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $ApplicationId, $SecuredPassword
Connect-AzAccount -ServicePrincipal -TenantId $TenantId -Credential $Credential
$sub = Get-AzSubscription -SubscriptionId $subscriptionId
Set-AzContext -Subscription $sub
I have reproduced in my environment and below script worked for me :
$appId ="53f3ed85-70c1c2d4aeac"
$pswd="55z8Q~_N9SRajza8R"
$t = "72f988bf-cd011db47"
[ValidateNotNullOrEmpty()]$pswd="55z8BU4oik.kVrZWyaK8R" $sp = ConvertTo-SecureString -String $pswd -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $appId, $sp
Connect-AzAccount -ServicePrincipal -TenantId $t -Credential $Credential
Output:
You need to convert the secret value(password) into secured password like above, then it will work as mine worked.

PowerShell - How do I bulk upload Certificates to an Azure App Registration Certificate store?

As you can see from the code below I can upload on certificate at a time, but the problem is it wipes out all of the existing certificates when doing so.
$Tenant_ID = '00000000-0000-0000-0000-000000000000'
$Subscription_ID = '00000000-0000-0000-0000-000000000000'
$Azure_PassWord = (Get-StoredCredential -Target 'Domain' -Type Generic -AsCredentialObject).Password
$UserName = "$($env:USERNAME)#Google.com"
$EncryptedPassword = ConvertTo-SecureString $Azure_PassWord -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PsCredential($UserName,$EncryptedPassword)
$AzureConnection = (Connect-AzAccount -Credential $Credential -Tenant $Tenant_ID -Subscription $Subscription_ID -WarningAction 'Ignore').context
$AzureContext = (Set-AzContext -SubscriptionName $Subscription_ID -DefaultProfile $AzureConnection)
$Application_ID = '00000000-0000-0000-0000-000000000000'
$PFX_FileName = "Azure_Dev_V2"
$Cert_Password = "123456"
$Cert_Password = ConvertTo-SecureString -String $Cert_Password -Force -AsPlainText
$CurrentDate = Get-Date
$EndDate = $CurrentDate.AddYears(10)
$certificatePath = "C:\FilePath\Certificates\Certs\$($PFX_FileName).pfx" # OR Get-ChildItem -Path cert:\localmachine\my\$($Certificate_Thumbprint)
$cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2($certificatePath, $Cert_Password)
$keyValue = [System.Convert]::ToBase64String($cert.GetRawCertData())
$Azure_App_Registration = Get-AzADApplication -ApplicationId $Application_ID -DefaultProfile $AzureContext
New-AzADAppCredential -ApplicationObject $Azure_App_Registration -CertValue $keyValue -EndDate $EndDate -StartDate $CurrentDate
Connect-AzAccount -Subscription $Subscription_ID -ApplicationId $Azure_App_Registration.AppId -Tenant $Tenant_ID -CertificateThumbprint $cert.Thumbprint | Out-Null
Get-AzADAppCredential -ApplicationId $Azure_App_Registration.AppId | Where-Object {$_.DisplayName -match "CN=Azure_Dev_V2"}
In the Azure portal multiple certificates can be uploaded manually, and they will not delete the existing certificates.
EDIT: If bulk upload is not possible then how would I go about making sure the existing certificates that are in the Azure AD App Registration cert store do not get deleted ?
Thanks in Advance.

Creating azure ad group with group types "Unified" and "DynamicMembership" fails in azure powershell function

I am using AzureAdPreview moudule and with the help of this I am trying to create a group with types "Unified" as well as "DynamicMembership".
So as per microsoft doc this is the command I have used
Import-Module AzureADPreview -UseWindowsPowerShell
$tenantId = <my tenant id>
$clientId = <my client id>
$thumbprint = <my thumbprint>
Connect-AzureAD -TenantId $tenantId -ApplicationId $clientId -CertificateThumbprint $thumbprint
New-AzureADMSGroup -Description $description -DisplayName `
$displayName -MailEnabled $true -SecurityEnabled $true `
-MailNickname $nickName -GroupTypes "DynamicMembership", "Unified"
-MembershipRule '(user.department -contains "tech")' -MembershipRuleProcessingState $true
But I am getting always invalid value provided in grouptypes error.
In an sligtly different approach, I have tried creating the group first with unified type, and then queried back the same group and appended grouptype to "DynamicMembership",I expected that to work but that also didn't make any difference.
Just like this -
New-AzureADMSGroup -Description $description -DisplayName `
$displayName -MailEnabled $true -SecurityEnabled $true `
-MailNickname $nickName -GroupTypes "Unified"
$grp = Get-AzureADMSGroup -SearchString $displayName
if($grp -ne $null)
{
[System.Collections.ArrayList]$groupTypes = $grp.GroupTypes
$groupTypes.Add($dynamicGroupTypes)
Set-AzureAdMsGroup -Id $grp.Id `
-GroupTypes $dynamicGroupTypes `
-MembershipRuleProcessingState "On" `
-MembershipRule $memberShipRule
}
Can you tell what I am doing wrong, this is working fine in a windows powershell. I am not able to understand what is malformed about that grouptypes.
• You are making some basic mistakes in the command that you are using for creating a ‘Unified’ and ‘Dynamic’ group through using powershell command in the Azure function. The command execution in Azure function involves the use of ‘AzureADPreview’ module only. Thus, you will have to uninstall and remove the ‘AzureAD’ module from your list of modules installed in powershell. For this purpose, execute the below command first: -
Remove-Module AzureAD -ErrorAction SilentlyContinue
Once done, then install the AzureADPreview module as you have done in your stated command. Then, execute the ‘Connect-AzureAD’ command as you have done. Then, execute the command as stated by me below for errorless execution as it is from start to end. Please do not forget to declare the other variables that you did in your question description for ‘Client ID’, ‘Tenant ID’ and ‘Thumbprint’: -
$tenantId = 'my tenant id'
$clientId = 'my client id'
$thumbprint = 'my thumbprint'
$description = ‘Description of the group’
$displayName = ‘Display Name to be given’
$nickName = ‘Any name of the group’
Connect-AzureAD -TenantId $tenantId -ApplicationId $clientId -CertificateThumbprint $thumbprint
New-AzureADMSGroup -Description $description -DisplayName $displayName -MailEnabled $true -SecurityEnabled $true -MailNickname $nickName -GroupTypes "DynamicMembership", "Unified" -MembershipRule “(user.department -contains “"tech"”)” -MembershipRuleProcessingState “On”
Once the above command is executed as it is, your command will be executed successfully in Azure function without any error or issue.

How to retrieve storage account key using powershell function app?

I'm using powershell function app to retrieve storage account key but i'm not able to access resources .Please help me .
$resourceGroup = "DemoResourceGroup"
$AccountName = "Demo"
$Key = (Get-AzStorageAccountKey -ResourceGroupName $resourceGroup -Name $AccountName)
Write-Host "storage account key 1 = " $Key
I'm getting following error :
2020-05-14T14:00:05Z [Error] ERROR: Get-AzStorageAccountKey : 'this.Client.SubscriptionId' cannot be null.
At D:\home\site\wwwroot\TimerTrigger1\run.ps1:25 char:8
+ $key = Get-AzStorageAccountKey -ResourceGroupName "DocumentParser_FBI ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Get-AzStorageAccountKey], ValidationException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Management.Storage.GetAzureStorageAccountKeyCommand
Script stack trace:
at , D:\home\site\wwwroot\TimerTrigger1\run.ps1: line 25
Microsoft.Rest.ValidationException: 'this.Client.SubscriptionId' cannot be null.
at Microsoft.Azure.Management.Storage.StorageAccountsOperations.ListKeysWithHttpMessagesAsync(String resourceGroupName, String accountName, Nullable1 expand, Dictionary2 customHeaders, CancellationToken cancellationToken)
at Microsoft.Azure.Management.Storage.StorageAccountsOperationsExtensions.ListKeysAsync(IStorageAccountsOperations operations, String resourceGroupName, String accountName, Nullable1 expand, CancellationToken cancellationToken)
at Microsoft.Azure.Management.Storage.StorageAccountsOperationsExtensions.ListKeys(IStorageAccountsOperations operations, String resourceGroupName, String accountName, Nullable1 expand)
at Microsoft.Azure.Commands.Management.Storage.GetAzureStorageAccountKeyCommand.ExecuteCmdlet()
According to the script you provide, you use Az module. So if you want to choose which Azure subscription you use, you need to use the command Select-AzSubscription. Besides, you also can add -Subscription "<subscription Id>" in Connect-AzAccoun to ensure when you login, you choose the right subscription.
For example
Create the service principal
Import-Module Az.Resources # Imports the PSADPasswordCredential object
$credentials = New-Object Microsoft.Azure.Commands.ActiveDirectory.PSADPasswordCredential -Property #{ StartDate=Get-Date; EndDate=Get-Date -Year 2024; Password=<Choose a strong password>}
$sp = New-AzAdServicePrincipal -DisplayName ServicePrincipalName -PasswordCredential $credentials
assign the role to the service principal. For example, assign Contributor role to the sp at the subscription level
New-AzRoleAssignment -ApplicationId <service principal application ID> -RoleDefinitionName "Contributor" `
-Scope "/subscriptions/<subscription id>"
Script
$appId = "your sp app id"
$password = "your sp password"
$secpasswd = ConvertTo-SecureString $password -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ($appId, $secpasswd)
Connect-AzAccount -ServicePrincipal -Credential $mycreds -Tenant <you sp tenant id>
Get-AzSubscription -SubscriptionName "CSP Azure" | Select-AzSubscription
$resourceGroup = "nora4test"
$AccountName = "qsstorageacc"
$Key = (Get-AzStorageAccountKey -ResourceGroupName $resourceGroup -Name $AccountName)[0].Value
Write-Host "storage account key 1 = " $Key

Azure Analytics Database with automate Backup

The powershell is used to automate the backup of AAS instance.
The instance have Multi-factor authentication and I think that is the problem.
Powershell:
$TenantId = "TenentID"
$Cred = Get-AutomationPSCredential -Name 'SSASModelBackup'
$Server = "ServerName"
$RolloutEnvironment = "location.asazure.windows.net"
$ResourceGroup = "ReourceGroupName"
#Create Credentials to convertToSecureString
$applicationId = "applicationId "
$securePassword = "securePassword " | ConvertTo-SecureString -AsPlainText -Force $Credential = New-Object
-TypeName System.Management.Automation.PSCredential -ArgumentList $applicationId, $securePassword
#Define the list of AAS databases
$asDBs = #('database1','database2')
Write-Output "Logging in to Azure..."
#Add-AzureAnalysisServicesAccount -Credential $Credential -ServicePrincipal -TenantId $TenantId -RolloutEnvironment $RolloutEnvironment
ForEach($db in $asDBs)
{
Write-Output "Starting Backup..."
Backup-ASDatabase `
–backupfile ($db +"." + (Get-Date).ToString("ddMMyyyy") + ".abf") `
–name $db `
-server $Server `
-Credential $Cred
Write-Output "Backup Completed!"
}
You are correct that the issue is with multi-factor authentication. Since the point of multi-factor is the require interaction with a secondary source like your phone there is no way to automate the process.
I would suggest that you look into using service principle authentication for the purpose of taking backups. By using a service principle to your server you can allow for automated tasks to run without 2-factor while minimizing the security risk.

Resources