This is more a sanity check because I've solved the problem but I'm unconvinced I've done it the smart way.
The Problem
I have some instances that have been assigned an IAM roles that allow them to access an S3 bucket. I then need to run some PowerShell scripts that will access that S3 bucket to download some objects.
The Solution
To get/set the credentials to use I've written this PowerShell function:
function Set-MyInstanceProfileCredentials {
param(
[parameter()]
[string]
$StoredCredentialsName = "MyInstanceProfileCredentials"
)
$Uri = "http://169.254.169.254/latest/meta-data/iam/security-credentials/"
Write-Verbose "Retrieving instance profile from $($Uri)"
$Uri = "$Uri$(Invoke-RestMethod -Uri $Uri)"
Write-Verbose "Retrieving security credentials from $($Uri)"
$Response = Invoke-RestMethod -Uri $Uri
Set-AWSCredentials -AccessKey $Response.AccessKey -SecretKey $Response.SecretAccessKey -StoreAs $StoredCredentialsName
Get-AWSCredentials -StoredCredentials $StoredCredentialsName
}
Then when I need to run a PowerShell cmdlet from the AWS module I just call this function first.
However I can't shake the feeling that I've missed something from the AWS PowerShell module that is already taking care of this for me.
However I can't shake the feeling that I've missed something from the AWS PowerShell module that is already taking care of this for me.
:) - you will be delighted to hear that this simply works out of the box indeed, i.e. the AWS Tools for Windows PowerShell is build upon the AWS SDK for .NET, which is handling this automatically, see also Credentials Search Order:
When you run a command, PowerShell Tools searches for credentials in the following order and uses the first available set.
[...]
6) If you are using running the command on an Amazon EC2 instance that is configured for an IAM role, use EC2 instance credentials stored in an instance profile.
For more information about using IAM roles for Amazon EC2 Instances, go to the AWS Developer Guide for .NET.
Related
I could not assign TokenLifetimePolicy Azure AD application policy from PowerShell. I had an error BadRequest : Message: Open navigation properties are not supported on OpenTypes.Property name: 'policies
I am trying to implement token expiry time from Configurable token lifetimes in Azure Active Directory
See screenshot below, any useful links and solutions on the AzureAD cmdlet Add-AzureADApplicationPolicy are welcome
I made it work by only using New-AzureADPolicy cmdlet and setting -IsOrganizationDefault $true not $false. The effect takes a while for you to see it. So wait for about 30 minutes to an hour (I don't know how long exactly). After that your new policy will be created and applied. Also remember that this is PowerShell, so no whitespaces in the cmdlet.
Example:
New-AzureADPolicy -Definition #('{"TokenLifetimePolicy":{"Version":1,"AccessTokenLifetime":"02:00:00","MaxInactiveTime":"02:00:00","MaxAgeSessionSingleFactor":"02:00:00"}}') -DisplayName "PolicyScenario" -IsOrganizationDefault $true -Type "TokenLifetimePolicy"
Multi-Line version:
New-AzureADPolicy -Definition #(
'
{
"TokenLifetimePolicy":
{
"Version": 1,
"AccessTokenLifetime": "02:00:00",
"MaxInactiveTime": "02:00:00",
"MaxAgeSessionSingleFactor": "02:00:00"
}
}
'
) -DisplayName "PolicyScenario" -IsOrganizationDefault $true -Type "TokenLifetimePolicy"
Microsoft may fix the issue with IsOrganizationDefault $true. Read more on this in the question: Azure AD Configurable Token Lifetimes not being Applied.
I test this quite a bit for my customers. I run into issues like this every now and then due to not on the latest version of PowerShell.
get-module
Latest Version 2.0.0.114 at the moment for AzureADPreview (V2)
Instructions to download here
There was an issue with -IsOrganizationDefault $true as Seth has pointed out.
Another issue I've found is having multiple versions of PowerShell on your system and it's loading the wrong one that doesn't have the updated bits. I hit this last Friday - I had to wipe everything and reinstall - then it fixed it.
Also -
There is a difference between:
Add-AzureADApplicationPolicy
and
Add-AzureADServicePrincipalPolicy
One is for an application object and the other is for a ServicePrincipal. If you are applying it to say, a SAML-Based application, then you should apply it to the ServicePrincpal.
Note: There is a different ObjectID for the application object and the servicePrincipal object. Don't get these confused. For an experiment, run the two cmds against your application:
Get-AzureADServicePrincipal -SearchString <name of app>
Get-AzureADApplication -SearchString <name of app>
If you grab the wrong ObjectID - no go when you go to apply the policy
The sequence for these Policies are: ServicePrincipal -> Application -> Tenant (organization)
Was the application created in B2C portal?
Assuming the answer is yes, this behavior is expected:
Microsoft has 2 authorization end points, V1 and V2.
B2C portal creates V2 apps. The token lifetime setting from powershell probably only works against the V1 apps.
There are settings on the b2c blade to change this.
The other option is to create an app from the azure active directory blade(as opposed to the b2c blade). Then you can set the token life time using powershell.
I am trying to remove deprecated cmdlets in a powershell script and one of the cmdlets is Select-AzureSubscription. I tried replacing it with Select-AzureRmSubscription but that requires user interaction to authenticate. Does anyone know what Azure-Rm cmdlet I should be using instead?
Select-AzureRmSubscription does change the approach that Azure uses for authentication. I had the same pain points when I converted my scripts.
The official way of approaching this via scripting is as follows -
$profile = Login-AzureRmAccount
Save-AzureRMProfile -Profile $profile -path $path
You can then use Select-AzureRmSubscription to none-interactively load those saved profiles.
Although ultimately I didn't go this route, I decided to add another layer of security and use a machine based certificate to encrypt / decrypt credentials to pass to Login-AzureRmAccount This way I could manage multiple sets of accounts and never have to be concerned about those tokens being exposed on vulnerable machines.
I'm trying to move some of my resources (Azure Web Apps, Azure SQLs, Redis caches) from one resource group to another. I'm using the Azure Resource Manager PowerShell cmdlets.
Here's what I've tried:
PS C:\> Move-AzureResource -DestinationResourceGroupName NewResourceGroup -ResourceId "/subscriptions/someguid/resourceGroups/Default-Web-WestEurope/providers/Microsoft.Web/sites/somesite"
Or:
PS C:\> Get-AzureResource -ResourceName somesite | Move-AzureResource -DestinationResourceGroupName NewResourceGroup
Or:
just Move-AzureResource, hitting enter and supplying the parameters one by one.
None of the commands seems to work. They just don't do anything. No error, no output.
When I changed the debug preference to $DebugPreference = "Continue" I got only the following:
DEBUG: 12:16:06 - MoveAzureResourceCommand begin processing with ParameterSet '__AllParameterSets'.
DEBUG: 12:16:06 - using account id 'my#account.tld'...
Please note that I'm able to create a new resource group (New-AzureResourceGroup), list resource groups (Get-AzureResourceGroup), list resources (Get-AzureResource), etc.
Note: you have to call Switch-AzureMode AzureResourceManager before you can use the cmdlets. The authentication is done by Add-AzureAccount.
Articles I've been referring to:
Moving resources between Azure Resource Groups
Move-AzureResource
Using Azure PowerShell with Azure Resource Manager
GitHub - Using Azure PowerShell with Azure Resource Manager
Reading this azure forum it looks like they have implemented the cmdlet but not all resources support being moved yet.
We have released a new powershell cmdlet to move resources across resource groups. Not all resources have support yet, but the "main" ones do like hosted services, virtual machines & storage accounts.
Looking back at the example I was following, this does only use VM's. So based on this I think websites aren't supported yet. That fact that no error or warning is returned for unsupported resources is a bit poor.
Though not all resources are currently supported, I understand the current version - 0.9.1 - does have a bug which means that even a supported resource may not be moved with the symptoms as seen by the author of the question. I understand this is being worked on for the next release, but in the interim (as a temp. work around) the previous powershell cmdlets release of 2 versions ago should work fine. https://github.com/Azure/azure-powershell/releases
The original issue is fixed in the 0.9.4 release. I just tried and it works.
FYI. To move a VM using Move-AzureResourceGroup you need to move the containing cloud service and all its VMs at the same time. For example:
Get-AzureResource -ResourceGroupName OriginalResourceGroup | where { $_.ResourceType -match 'Microsoft.ClassicCompute' } | Move-AzureResource -DestinationResourceGroupName NewResourceGroup
By default, the resources in a cloud service are put in a resource group with the same name as the DNS name of the cloud service.
For some reason, Azure PowerShell Version 1.0 has trouble moving over web apps from one Resource Group to another. If you follow the instrctions below, you will be able to move the web app over via powershell.
Download Azure PowerShell Version 1. The below instructions only work for this version. Type the commands below in order.
1) **Login-AzureRmAccount** (a login window will pop up asking for your azure credentials, type them in)
2) **Get-AzureRmResource -ResourceGroupName "NameOfResourceGroup" -ResourceName "WebAppName"** (if you are moving over a website, you will see 2 files, you need the one that is a resource type of Microsoft.Web/sites)
3) **Get-AzureRmResource -ResourceGroupName "NameOfResourceGroup" -ResourceName "WebAppName" -ResourceType "Microsoft.Web/sites"**
4) Assign value 3 to a variable of your name choice. I Chose $a, so **$a = Get-AzureRmResource -ResourceGroupName "NameOfResourceGroup" -ResourceName "WebAppName" -ResourceType "Microsoft.Web/sites"**
5) **Move-AzureRmResource -DestinationResourceGroup "DestinationResourceGroup" -ResourceId $a.ResourceId**
6) It will ask you if you are sure type "Y" and hit enter.
Using PowerShell DSC, I'm trying to read an object from within an AWS S3 bucket but I get the following error:
Unable to load stored credentials for profile = [default]
I have tried using the -ProfileLocation parameter however that then throw the error "A parameter cannot be found that matches parameter name 'ProfileLocation'". My code is as follows:
Read-S3Object -ProfileName default BucketName $bucket -Key $key -File $file
Make sure you have read this documentation "Using AWS Credentials" and followed the instructions it provided.
Troubleshooting
ProfileName is not supported in the AWS Powershell Tools prior to version v1.1. You can check your version through the Get-AWSPowerShellVersion cmdlet. If you are using an earlier version, try using the StoredCredentials parameter instead. Alternatively, you can update.
Make sure that the profile name "default" actually exists. You can check this by running Get-AWSCredentials -ListStoredCredentials, which will return a list of stored AWS credentials.
If your desired profile name does not exist, you will need to create it.
The documentation provides the following example for creating a new profile:
Set-AWSCredentials -AccessKey AKIAIOSFODNN7EXAMPLE `
-SecretKey wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY `
-StoreAs MyProfileName
Note: Concerning terminology, Stored Credential and Profile seem to be used interchangeably by the documentation.
I'm using the Windows Azure PowerShell Cmdlets v0.6.7 from here: https://www.windowsazure.com/en-us/manage/downloads/
When I run the following command:
Move-AzureDeployment -ServiceName $AzureServiceName
I get the following error:
Move-AzureDeployment : There was no endpoint listening at https://management.core.windows.net/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/services/hostedservices/xxxxxxxxxxxxxxx/deploymentslots/Production that could accept the message.
The error is somewhat correct, there is only a deployment in my Staging slot. However, the documentation for Move-AzureDeployment (http://msdn.microsoft.com/en-us/library/windowsazure/jj152834.aspx) states:
If there is a deployment in the staging environment and no deployment
in the production environment, the deployment will move to production.
The preceding Azure PowerShell Cmdlets in the same script, such as New-AzureDeployment, execute successfully. I start the script by using Set-AzureSubscription to configure the subscription info and certificate.
Not sure what I'm missing, any help is appreciated, thanks!
I ran into this issue as well and resorted to using the REST API for swapping. Here is a sample in case anyone is interested.
$webRequest = [System.Net.WebRequest]::Create("https://management.core.windows.net/$global:SubscriptionId/services/hostedservices/$serviceName")
$webRequestContent = ("<?xml version=""1.0"" encoding=""utf-8""?><Swap xmlns=""http://schemas.microsoft.com/windowsazure""><Production>{0}</Production><SourceDeployment>{1}</SourceDeployment></Swap>" -f $productionDeploymentName, $stagingDeploymentName)
$webRequest.Method = "POST"
$webRequest.ClientCertificates.Add($global:ManagementCertificate)
$webRequest.ContentType = "application/xml"
$webRequest.ContentLength = $webRequestContent.length
$webRequest.Headers.Add("x-ms-version", "2012-03-01")
$writer = New-Object System.IO.StreamWriter($webRequest.GetRequestStream())
$writer.Write($webRequestContent)
$writer.Close()
$webResponse = $webRequest.GetResponse()
WaitForDeploymentState $serviceName 'Production' 'Running'
WaitForRoleInstancesState $serviceName 'Production' 'ReadyRole'
I think there is a bug. I created an issue here:
https://github.com/WindowsAzure/azure-sdk-tools/issues/785
I found this when I hit the same problem.
In my script, if I want to run the Move-AzureDeployment I first check the Production slot, if it has content then I switch (having already deployed to staging earlier in the script).
In the case where Production is empty I re-deploy the current package to the Production Slot, I could optimize it to use the azure storage but it'll do for today.
In short; the docs are either wrong or there is a bug, you cannot use this cmdlet if Production is empty.