I'm using azure automation to automate a process with a Powershell Workflow Runbook. In that process I connect to MSOnline and Exchange with a Credential:
# Pull credential from Automation assets
$cred = Get-AutomationPSCredential -Name "CredentialName"
# Connect To Microsoft online
Connect-MsolService -Credential $cred
# Connect to Exchange Online
$ExchangeOnlineSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $cred -Authentication Basic -AllowRedirection -Name $ConnectionName
Import-Module (Import-PSSession -Session $ExchangeOnlineSession -AllowClobber -DisableNameChecking) -Global
This works but I don't want to save credentials of an account with permissions, the $cred.
I read and (thought I) understood that this could be done with a Service Principle Account. The problem is that I don't find it good described in order for me to make it work, although I have tried many times.
Any information is welcome
When you say you're using "Azure Automation" to automate a process, I believe you must have provisioned an Azure Automation Account to hold the PS Runbook & authenticate to Azure resources.
When you setup an Azure Automation Account, there's a built-in feature "Run As Accounts". It creates a Run-As account which takes care of the following tasks for the user:
Create a Service Principal in Azure AD
Create a Certificate
Assigns the Contributor Role-Based Access Control (RBAC), which manages Azure Resource Manager resources by using runbooks
One point to note here is that, the Service Principal for a Run as Account does not have permissions to read Azure AD by default. If you want to add permissions to read or manage Azure AD, you'll need to grant the permissions on the service principal under API permissions.
Once you're all set with Run As Account, you can use the account and retrieve the connection with Get-AzAutomationConnection
You can refer this documentation for more details: Manage Azure Automation Run As Accounts
Hope this helps!
Related
I have made one script in which i need to connect the connect-exchangeonline and connect-msolservice.
I am using the MFA credential to connect these services
Is there anyway where we can connect these two services with single credential or can we save the MFA credential in variable from where we can use to connect both services?
Thanks in advance
Microsoft says you can use:
$acctName="<UPN of the account, such as belindan#litwareinc.onmicrosoft.com>"
$orgName="<for example, litwareinc for litwareinc.onmicrosoft.com>"
#Azure Active Directory
Connect-MsolService
#Exchange Online
Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline -UserPrincipalName $acctName -ShowProgress $true
I wrote a program in Powershell which runs on a schedule in an Azure Functions app. To avoid hard-coded credentials, I created an Azure Key Vault to store the secrets. I created a managed identity in the Azure Function, created the secrets in Azure Key Vault and then created application settings in Azure Function with the URL to point at the secrets in Azure Key Vault. The program references the application secrets (APPSETTING) and behaves as expected:
$uSecret = $ENV:APPSETTING_SecretUsername
$pSecret = $ENV:APPSETTING_SecretPassword
$sasSecret = $ENV:APPSETTING_SecretSAS
$securePassword = ConvertTo-SecureString -String $pSecret -AsPlainText -Force
$UserCredential = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList $uSecret, $securePassword
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
However I noticed that if I run the same program on my local computer via Windows Powershell (run as Administrator) and with the above lines amended as follows, the program runs fine - meaning it can access Office 365 and the data lake storage:
$uSecret = (Get-AzKeyVaultSecret -VaultName 'auditkeyvault' -Name 'SecretUsername').SecretValueText
$pSecret = (Get-AzKeyVaultSecret -VaultName 'auditkeyvault' -Name 'SecretPassword').SecretValueText
$sasSecret = (Get-AzKeyVaultSecret -VaultName 'auditkeyvault' -Name 'SecretSAS').SecretValueText
$securePassword = ConvertTo-SecureString -String $pSecret -AsPlainText -Force
$UserCredential = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList $uSecret, $securePassword
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
Why am I able to run this locally on my computer? I would have expected only the Azure Functions app to be able to retrieve the secrets from Azure Key Vault and that any other resource such as my local computer would be prevented?
Isn't the whole purpose of creating a managed identity for the Azure Function with the specific URL, so that it could identify itself as the authenticated/authorised resource to access the keys? Yet when I run the program locally above with (Get-AzKeyVaultSecret -VaultName 'auditkeyvault' -Name 'SecretUsername').SecretValueText, my program is still able to retrieve the keys and run!
Can someone please shed some light on why this is happening or if I have misunderstood something?
Many thanks!
(PS. This is all running on a trial instance with sample data, so no real data is compromised at the moment)
The purpose of the keyvault is keep your secrets securely.
Any authorized credentials (through the Keyvault access policies) can access those secrets through the REST api.
To access the secrets, you need:
An access policy in the keyvault that allow you sufficient access
To be authenticated with an authorized account
Get-AzKeyVaultSecret is just another way to retrieve secret.
It work on your computer because your session is still authenticated and your AzureAd account have read access to that keyvault secret.
You can effectively use any Az command without re-authenticating everytime.
Call Get-AzContext to get the current context details.
Connect-AzAccount do save your access tokens and other relevant informations when used automatically at the following location: C:\Users\MAK\.Azure\AzureRmContext.json
If you were to disconnect first Disconnect-AzAccount and trying to get the secret again without re-authenticating, then it would fail.
Note
If you are not comfortable with the Az module saving your tokens on disk, you can disable the default behavior through Disable-AzContextAutosave
I have a powershell script that MS provided and I have edited. True to form MS has provided a script using old code. Since we have MFA enabled, I can no longer use Get-Credential to authenticate as we use Modern Auth instead of Basic. How can I edit the code to support MFA? We do not use Auzer MFA we use Duo.
Old Code:
$adminCredential = Get-Credential
Write-Output "Connecting to Exchange Online Remote Powershell Service"
$ExoSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $adminCredential -Authentication Basic -AllowRedirection
if ($null -ne $ExoSession) {
Import-PSSession $ExoSession -AllowClobber
} else {
Write-Output " No EXO service set up for this account"
}
Write-Output "Connecting to EOP Powershell Service"
$EopSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.compliance.protection.outlook.com/powershell-liveid/ -Credential $adminCredential -Authentication Basic -AllowRedirection
if ($null -ne $EopSession) {
Import-PSSession $EopSession -AllowClobber
} else {
Write-Output " No EOP service set up for this account"
}
The new commands should be Connect-IPPSSession instead of New-PSSession but I have to somehow change Get-Credential to pass the credentials and MFA I just have no idea how to do this.
Full disclosure, neither I nor any the customers I support use Duo.
That being said, there are no docs from MS regarding PowerShell and MFA using DUO as the source for O365.
As per MS...
Connect to Office 365 services with multifactor authentication (MFA) and PowerShell
Connect to Exchange Online PowerShell using multi-factor authentication
You can't use the Exchange Online Remote PowerShell Module to connect to Exchange Online PowerShell and Security & Compliance Center PowerShell in the same session (window). You need to use separate sessions of the Exchange Online Remote PowerShell Module.
If you want to use multi-factor authentication (MFA) to connect to Exchange Online PowerShell, you can't use the instructions at Connect to Exchange Online PowerShell
https://learn.microsoft.com/en-us/powershell/exchange/exchange-online/connect-to-exchange-online-powershell/connect-to-exchange-online-powershell?view=exchange-ps
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
to use remote PowerShell to connect to Exchange Online.
MFA requires you to install the Exchange Online Remote PowerShell Module, and use the Connect-EXOPSSession cmdlet to connect.
Connect-EXOPSSession -UserPrincipalName <UPN> [-ConnectionUri <ConnectionUri> -AzureADAuthorizationEndPointUri <AzureADUri>]
Multi-Factor Authentication (MFA) Setup and End-User Experience with Office 365 and PowerShell
See also, if you have not already.
How do I change the username format sent to Duo?
If you want to use OAuth authentication, you need to have Access Token
Once the application has an access token, it may use the token to access the user's account via the API, limited to the scope of access, until the token expires or is revoked.
Here is an example of an API request, using curl. Note that it includes the access token:
curl -X POST -H "Authorization: Bearer ACCESS_TOKEN""https://api.digitalocean.com/v2/$OBJECT"
You can Authenticate Against OAuth refer the below link:
Using PowerShell to Authenticate Against OAuth
Upon reading the answers I realize that I did not structure my question in a detailed enough manner for the answer I need. I am leaving the question live and marking one of the answers as the answer because it does answer the question I asked, just not what I was hoping to learn.
The Connect-ExchangeOnline supports login with 2FA. You can run it as is without any arguments.
I want to execute some PowerShell scripts on our TFS Release Manager environment that use AzureAD module to provision some Azure AD groups. The scripts are executed using an Azure Powershell Task. I've installed the AzureAD module, so the AzureAD PowerShell CmdLets are recognized.
However, for them to work the scripts first needs to connect to AzureAD using the Connect-AzureAD CmdLet. This CmdLet wants to show a modal dialog for entering credentials, which obviously isn't possible in a Release Manager task. I also cannot supply credentials using command line parameters. I want Connect-AzureAD to somehow use the current user context for the connection. Is this possible?
You could use the -Credential option of Connect-AzureAD.
In your AzureAD task, you can use the following code:
```
$pass=ConvertTo-SecureString $Env:password -AsPlainText -Force
$credential=New-Object PSCredential($Env:login, $pass)
Connect-AzureAD -Credential $credential
```
login and password are stored in a secret variable in the release definition.
Alternatively you might get the password from a previous task in the build definition. I that case, in the script arguments of the task, you pass the password -password "$(password)"
and in the `Script or Script inline you have, this time:
``
param([string]$password)
$pass=ConvertTo-SecureString $password -AsPlainText -Force
$credential = New-Object PSCredential($Env:login, $pass)
Connect-AzureAD -Credential $credential
``
I get the password from KeyVault with the Azure KeyVault task, but that might not be an option for you if you are on premise.
We've found an answer. It had been setting right in front of us on the official Connect-AzureAD documentation page (example 3).
So we're now authenticating using a SPN and a self-signed certificate. This works just fine.
When creating a new PS Session to our Exchange 2010 server:
$session = New-PSSession -ConfigurationName microsoft.exchange -ConnectionURI http://exchange.domain.com/powershell -Credential $cred
And importing the newly created session:
Import-PSSession $session
This would give me a slew of Exchange cmdlets that I can now use locally within my Powershell session. Unfortunately, it seems to be missing a few cmdlets that I need to automate some mailbox actions. Specifically -- Set-UMMailbox, which would allow me to change the operator's phone number on the mailbox.
Is this a bug with this particular configuration? Or am I missing something else?
If there is another way go to about doing this, I'm all ears. Thanks.
I found out the issue here is related to permissions. The service account I was using had a majority of the rights, but not rights to unified messaging. I tested this by using my domain admin account credentials (which I won't be using in my script).