How to log into AWS CLI with a federated SAML (AzureAD) login - powershell

I'm connecting to AWS using a SAML login with AzureAD as my IdP. This is all working great and I can use SAML response in the browser to generate a temporary session token that gives me an hour to work in AWS CLI. However, according to this blog, I should be able to use AWS Tools for Windows PowerShell to capture the SAML Response but all I ever get is an error Unable to set credentials: Root element is missing. All my googling is leading to possible transient issues with certificates being near expiration or using older versions of the Powershell Module (I'm using the latest as of this writing: v4.1.13.0) or Powershell itself (I'm using 7.1.3).
Anybody successfully got the AWS Tools for Windows PowerShell to work with AzureAD as an IdP?

I found this somewhat more recent post, which has a ton more information about this kind of setup, some detail about how to configure it, and a note about why it may not be working (as of Jan2020)
Try using the AWSPowerShell command Use-STSRoleWithSAML(AWS docs) to generate some temporary credentials. The doc page goes into a lot of detail on what is required too for your Idp and in IAM, including links to relevant IAM guides. For example:
# Returns a set of temporary security credentials
Use-STSRoleWithSAML `
-RoleArn 'arn:aws:iam::ACCOUNTNUMBER:role/IAMROLE' `
-PrincipalArn 'arn:aws:iam::ACCOUNTNUMBER:saml-provider/SAMLPROVIDER' `
-SAMLAssertion 'BASE64ENCODEDRESPONSE' `
-DurationInSeconds 3600

Related

How do I do authentication for my powershell scripts for Microsoft 365/AzureAD/Exchange Online automation?

So I can successfully run commands to manage our Microsoft 365/AzureAd/Exchange Online - this involves assigning and removing license, converting user to a shared mailbox, delegating access to a mailbox, etc. I followed the guide here for authentication. But that's me actually logging in with my credentials + MFA (Multi-factor authentication) for authentication.
I want to have a script that does these type of actions triggered by a schedule. I believe I can include the credentials but how to do MFA? Tried to follow this but getting error clientid is not a guid I have registered an app in https://portal.azure.com/ and able to do Graph API calls using that. No luck in PowerShell authentication though. Any thoughts? Thanks!
Maybe try this? It should allow you to connect to all Microsoft online services and includes support for MFA. If it does not work, the website has many other scripts you can try
This is not possible. A potential solution is to set some rules where in specific case, MFA will not be required.

Powershell - automated connection to Power BI service without hardcoding password

We have a PowerShell script to pull Power BI activity data (using Get-PowerBIActivityEvent), and I have been trying to automate it so that it can pull this data daily using an unattended account. The problem is the script must necessarily use the Connect-PowerBIServiceAccount cmdlet, which requires a credential. I don't want to have the passwords hard-coded anywhere (obviously) and ideally don't want to be passing it into the script as a plaintext parameter in case of memory leaks.
I've tried using SSIS as a scheduling mechanism since it allows for encrypted parameters in script tasks, but can't call the PS script with a SecureString parameter since the System.Management.Automation namespace isn't in the GAC (a commandline call wouldn't be possible).
I don't believe task scheduler would offer the functionality needed.
Does anyone know of any elegant ways to connect to the power BI service using encrypted credentials?
In the docs of Connect-PowerBIServiceAccount there are 2 options for unattended sign-in:
Using -Credential, where you pass AAD client ID as username and application secret key as password
Using -CertificateThumbprint and -ApplicationId
For both options you need to configure service pricipal and add proper permissions. I'm not going into details how to configure that, but most probably you'd need (at least) the following application permissions:
I'm not really sure what functionalities you need in the script, but in my experience, majority of the cases can be covered by scheduled task, so the explanation below will apply to that solution.
How you can secure the credentials?
There are variuos possible solutions, depending on your preferences. I'd consider certificate-based authentication as more secure (certificate is available only to current user/all users of the machine).
What's important in certificate-based authentication - make sure that the certificate is available for the account running the script (in many cases it's service account, not your user account).
How can I secure more?
If you want, you can store application ID as secure string (I don't have SSIS to test, so I'm not sure if there's any workaround to make it working in there) or use Export-CliXml. They use Windows Data Protection API (DPAPI), so the file can be decrypted only by the account which was used to encrypt.
To add one more level of security (I'm not even mentioning setting correct access rights to the files as it's obvious) you might put the file in the folder encrypted (you might already have a solution for disk encryption, so use it if you wish).
There are probably some solutions to secure the keys even better, but these ones should do the job. I'm using other Microsoft 365 modules with similar approach (Outlook, SharePoint PnP) and it works quite well.
NOTE: If you need to use user account, instead of service principal, make sure that you have MultiFactor Authentication disabled on that account for that specific application.
The relevant documentation to this (https://learn.microsoft.com/en-us/power-bi/developer/embedded/embed-service-principal) states that admin APIs (i.e. those served via Get-PowerBiActivityEvent) do not currently support service principals. This means it's not currently possible to use a registered app to run these cmdlets unattended.
There is a feature request open to provide this at the moment: https://ideas.powerbi.com/forums/265200-power-bi-ideas/suggestions/39641572-need-service-principle-support-for-admin-api

Connecting to Exchange Online with PowerShell and Modern Authentication (without any dependencies)

I want to connect to Exchange Online using PowerShell and modern authentication without depending on any modules or dll's.
There's a module available for modern authentication to Exchange Online that depends on the CreateEXOPSSession.ps1 and Microsoft.Exchange.Management.ExoPowerShellModule.dll, I have decompiled the latter and found that it generates an access token as such:
TokenInformation accessToken = TokenProviderFactory.Instance.CreateTokenProvider(new TokenProviderContext(authType, "a0c73c16-a7e3-4564-9a95-2bdf47383716", this.AzureADAuthorizationEndpointUri, acquireTokenEndpoint, this.UserPrincipalName, this.Credential, clientAppRedirectUri, (Action<string>) (s => this.WriteWarning(s)))).GetAccessToken();
I want to request the access token is the same way in PowerShell but I can't seem to get the right authentication context and method of retrieving the access token.
Any ideas?
You have to have an MSOL connection and create a remote session to EXO to use EXO cmdlets. There is no workaround for this.
The dependencies are there for a reason. The backend plumbing of MSOL / Azure / O365 expects what it expects, and skirting it will just lead you down a very frustrating/hair-pulling activity.
That token is an Azure AD as MA/ADAL requires that you have an Azure AD Premium license.
MA requires use of the ADAL API/DLL. This is like asking to programmatically connect to and use Exchange on-prem EAS/EWS services without using the API/DLL, that's not a thing either.
So, no matter how you look at this, there will be dependencies, as noted below. So, if you are serious about this effort, you need to really dig into what MA really is and how it's plumbing really works. Also, MFA must be already enabled for you and users, either in O365 and or the ADAL MFA settings in Azure.
Modern Authentication – What is it?
Modern Authentication brings Active Directory Authentication Library (ADAL)-based sign-in to Office client apps across platforms.
Microsoft identity platform authentication libraries
There is also an ADAL module on the MS PowerShellGallery.com.
Microsoft.ADAL.PowerShell 1.12
ADAL module for PowerShell
https://www.powershellgallery.com/packages/Microsoft.ADAL.PowerShell/1.12
Functions
Get-ADALAccessToken Clear-ADALAccessTokenCache
Examples are here:
Microsoft.ADAL.Powershell ```
####Example 1 This example acquire accesstoken by using RedirectUri from contoso.onmicrosoft.com Azure Active Directory for PowerBI
service. It will only prompt you to sign in for the first time, or
when cache is expired.
Get-ADALAccessToken -AuthorityName contoso.onmicrosoft.com `
-ClientId 8f710b23-d3ea-4dd3-8a0e-c5958a6bc16d `
-ResourceId https://analysis.windows.net/powerbi/api `
-RedirectUri "http://yourredirecturi.local"
See also:
Azure-AD-Authentication-with-PowerShell-and-ADAL
This is a set of really simple PowerShell scripts which allow you to get access tokens with Azure Active Directory using ADAL.
and this...
ADAL and PowerShell

Where is PowerShell for AWS getting its credential from?

I recently installed the AWS .NET SDK which came with the PowerShell For AWS CLI enhancements.
I went ahead and added an IAM user and generated a key pair, then installed it into the SDK Store:
Set-AWSCredentails -AccessKey AAAAAAAAAAAAAA -SecretKey AAAAAAAAAA/AAAA -StoreAs default
I then tested my credentials by making a request that I knew I didn't have access to:
Get-EC2Instance
... Then was surprised to find out print out three EC2 instances. Instances I don't own! I tried this as well:
Get-EC2Instance -Profile default
Which produced the desired result, insufficient access. To continue testing, I added EC2FullAccess to my user and repeated the last line. It correctly printed my personal use EC2 instance:
GroupNames : {}
Groups : {}
Instances : {aws_personal}
OwnerId : 835586800000
RequesterId :
ReservationId : r-0e625fd77d0000000
However whenever I attempt a statement without the -Profile default, I am accessing another account. Without going into too much detail, I disabled my access to that account in AWS Dashboard. Now commands produce this output:
Get-EC2Instance : AWS was not able to validate the provided access credentials
At line:1 char:1
+ Get-EC2Instance
I do not have a .AWS directory in my %UserProfile%. Searching my computer for .aws or credentials fails to find a credential file which would explain this.
I can't explain why you are seeing different behavior between specifying the -ProfileName parameter and not, but I can shed light on where credentials are coming from.
The PowerShell tools can read from two credential locations (as well as environment variables and EC2 instance metadata when running on an EC2 instance).
Firstly there is the encrypted SDK credential store file which is located at C:\Users\userid\AppData\Local\AWSToolkit\RegisteredAccounts.json - this one is shared between the PowerShell tools, the AWS SDK for .NET and the AWS Toolkit for Visual Studio. It can also read from the ini-format shared credentials file (shared with the AWS CLI and other AWS SDKs). Note that although the shared credentials file can be moved between accounts and machines, the encrypted SDK file can be used only by the owning user and only on that single machine.
The PowerShell tools currently only write to one store though - the encrypted file used by the .NET tools exclusively. So when you set up credentials and used the -StoreAs option, the profile would have been written to the RegisteredAccounts.json file. If you open this file in a text editor you should see your profile named 'default' along with two encrypted blobs that are your access and secret keys.
When a profile name is given with a command, the tools look for a profile with that name first in RegisteredAccounts.json and if not found there, it attempts to read the ini-format file in %USERPROFILE%.aws\credentials (to bypass the encrypted store, you can use the -ProfilesLocation parameter to point at the ini-format file you want to load credentials from, if it's not at its default location under your user profile).
If no profile name is given, the tools probe to find the closest set of credentials - the search 'path' is described in a blog post at https://blogs.aws.amazon.com/net/post/Tx2HQ4JRYLO7OC4/. Where you see references to loading a profile, remember that the tools check for the profile first in RegisteredAccounts.json and then in the shared credentials file.
HTH you track down where the tools are finding credentials.

How to add an SSL certificate to an azure website using powershell?

I am working on automatic deployment + azure. I'm at the point where i'm adding an ssl cert to the website. Does anyone know how to use PowerShell to upload an SSL certificate to a website using the PowerShell command (Add - Get - Set based commands)? I'm able to add a certificate to a cloud service using ...
New-AzureService $Program -Location 'East US'
Add-AzureCertificate -Password Cert123! -ServiceName $Program -CertToDeploy $CertLocation
but I have no idea how to add it to an azure website.
Thanks
edit: I've found a way using the following command, but i'm not wanting to install additional libraries on my production deployment machine.
azure site cert add -k Cert123! $CertLocation $Program
Using the newly released Azure PowerShell v. 1.1.0, you can use the following command to upload a certificate to your website
New-AzureRmWebAppSSLBinding -ResourceGroupName myresourcegroup -WebAppName mytestapp -CertificateFilePath PathToPfxFile -CertificatePassword PlainTextPwd -Name www.contoso.com
More information is in the following article
https://azure.microsoft.com/en-us/documentation/articles/app-service-web-app-powerhell-ssl-binding/
As far as I know the Azure PowerShell cmdlets do not offer this capability at the moment that I could find. As you point out the Cross Platform Command Line tool does. Since you don't want to add the XPlat-CLI tool to your deployment machines you can use what the XPlat-CLI tool does under the hood: a direct call against the REST api for web site management.
Note you'll need to figure out what webspace the site resides in, etc. You can use the Invoke-WebRequest to make this call so that you can verify you get that 200 response back. Or you could use the Invoke-RESTMethod as well, but that would only return an XML document (the contents of the response). The Invoke-WebRequest provides you a little more control and access to the full response object.
The Microsoft Azure Management Libraries (which the PowerShell cmdlets sit on top of) has a Web Site Management piece to it. One of the operations is an update to a site and that includes a WebSiteUpdateParameters object with a SSLCertificates property. You may check into that as well, though I've not done this myself.