I’ve done some Lambda functions with Python in the past and it was quite easy to publish that to Lambda (by just uploading a zip file with all my code and dependencies). You might ask yourself why I want to do that with PowerShell but the reason is quite simple: There was a requirement at a customer to automatically collect all the KBs that are installed in the AWS Windows WorkSpaces for compliance reasons. Doing that for EC2 or on-prem instances is quite easy using Lambda for Python against SSM when you are using SSM for patching, but if you want to list the installed KBs of your deployed AWS WorkSpaces you need a different way of doing that. After discussing that with AWS Support it turned out that the easiest solution for this is to use the PowerShell Get-HotFix module remotely against the AWS WorkSpaces. Easy, I thought, when I can deploy Python code in Lambda I can easily do this for PowerShell as well. But this is definitely not true as the process is quite different. So, here we go …
The first bit you need to prepare is a PowerShell development environment for AWS. As I am running Linux (KDE Neon, if you want to know exactly), and PowerShell is available on Linux since quite some time, I’ll be showing how to do that on Linux (the process is more or less the same for Windows though).
Obviously PowerShell needs to be installed and this is documented by Microsoft quite well, no need to further explain this. Basically it is matter of:
$ wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb $ sudo dpkg -i packages-microsoft-prod.deb $ sudo apt-get update $ sudo add-apt-repository universe $ sudo apt-get install -y powershell
… and that’s it (take care to follow the steps for your Linux distribution). Once that is done PowerShell can be started:
$ pwsh PowerShell 7.0.2 Copyright (c) Microsoft Corporation. All rights reserved. https://aka.ms/powershell Type 'help' to get help. PS /home/dwe>
The first additional module you’ll need is AWSLambdaPSCore:
PS /home/dwe> Install-Module AWSLambdaPSCore -Scope CurrentUser Untrusted repository You are installing the modules from an untrusted repository. If you trust this repository, change its InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure you want to install the modules from 'PSGallery'? [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"): Y
Usually you want to work with other AWS Services in your Lambda code so it is recommended to install the AWS.Tools.Installer module as it provides a convenient way for installing the various tools required for working with the various AWS services. In addition the AWSPowerShell.NetCore module is required:
PS /home/dwe> Install-Module -Name AWS.Tools.Installer -Force PS /home/dwe> Install-Module -name AWSPowerShell.NetCore -Force
Now, dependend on which AWS services you want to work with, just install what you need (in this example EC2, S3 and WorkSpaces):
PS /home/dwe> Install-AWSToolsModule AWS.Tools.EC2,AWS.Tools.S3 -CleanUp -Force Installing module AWS.Tools.EC2 version 4.0.6.0 Installing module AWS.Tools.S3 version 4.0.6.0 PS /home/dwe> Install-AWSToolsModule AWS.Tools.Workspaces -CleanUp -Force Installing module AWS.Tools.WorkSpaces version 4.0.6.0
Once you have that ready you can use the AWS tools for PowerShell to generate a template you can start with:
PS /home/dwe> Get-AWSPowerShellLambdaTemplate Template Description -------- ----------- Basic Bare bones script CloudFormationCustomResource PowerShell handler base for use with CloudFormation custom resource events CodeCommitTrigger Script to process AWS CodeCommit Triggers DetectLabels Use Amazon Rekognition service to tag image files in S3 with detected labels. KinesisStreamProcessor Script to be process a Kinesis Stream S3Event Script to process S3 events S3EventToSNS Script to process SNS Records triggered by S3 events S3EventToSNSToSQS Script to process SQS Messages, subscribed to an SNS Topic that is triggered by S3 events S3EventToSQS Script to process SQS Messages triggered by S3 events SNSSubscription Script to be subscribed to an SNS Topic SNSToSQS Script to be subscribed to an SQS Queue, that is subscribed to an SNS Topic SQSQueueProcessor Script to be subscribed to an SQS Queue PS /home/dwe> cd ./Documents/aws PS /home/dwe/Documents/aws> New-AWSPowerShellLambda -ScriptName MyFirstPowershellLambda -Template Basic Configuring script to use installed version 4.0.6.0 of (@{ ModuleName = 'AWS.Tools.Common'; ModuleVersion = '4.0.5.0' }.Name) Created new AWS Lambda PowerShell script MyFirstPowershellLambda.ps1 from template Basic at /home/dwe/Documents/aws/MyFirstPowershellLambda PS /home/dwe/Documents/aws/MyFirstPowershellLambda> ls MyFirstPowershellLambda.ps1 readme.txt
The generated template is quite simple but it gives you an idea how to start:
PS /home/dwe/Documents/aws/MyFirstPowershellLambda> cat ./MyFirstPowershellLambda.ps1 # PowerShell script file to be executed as a AWS Lambda function. # # When executing in Lambda the following variables will be predefined. # $LambdaInput - A PSObject that contains the Lambda function input data. # $LambdaContext - An Amazon.Lambda.Core.ILambdaContext object that contains information about the currently running Lambda environment. # # The last item in the PowerShell pipeline will be returned as the result of the Lambda function. # # To include PowerShell modules with your Lambda function, like the AWS.Tools.S3 module, add a "#Requires" statement # indicating the module and version. If using an AWS.Tools.* module the AWS.Tools.Common module is also required. #Requires -Modules @{ModuleName='AWS.Tools.Common';ModuleVersion='4.0.6.0'} # Uncomment to send the input event to CloudWatch Logs # Write-Host (ConvertTo-Json -InputObject $LambdaInput -Compress -Depth 5)
Just add the modules for the specific AWS services you want to work with in the “#Requires” section (you need to install them before of course) and write your script:
PS /home/dwe/Documents/aws/MyFirstPowershellLambda> cat ./MyFirstPowershellLambda.ps1 # PowerShell script file to be executed as a AWS Lambda function. # # When executing in Lambda the following variables will be predefined. # $LambdaInput - A PSObject that contains the Lambda function input data. # $LambdaContext - An Amazon.Lambda.Core.ILambdaContext object that contains information about the currently running Lambda environment. # # The last item in the PowerShell pipeline will be returned as the result of the Lambda function. # # To include PowerShell modules with your Lambda function, like the AWS.Tools.S3 module, add a "#Requires" statement # indicating the module and version. If using an AWS.Tools.* module the AWS.Tools.Common module is also required. #Requires -Modules @{ModuleName='AWS.Tools.Common';ModuleVersion='4.0.6.0'} #Requires -Modules @{ModuleName='AWS.Tools.S3';ModuleVersion='4.0.6.0'} #Requires -Modules @{ModuleName='AWS.Tools.EC2';ModuleVersion='4.0.6.0'} # Uncomment to send the input event to CloudWatch Logs # Write-Host (ConvertTo-Json -InputObject $LambdaInput -Compress -Depth 5) Write-Output "Test"
The AWS documentation for the PowerShell Cmdlets is here.
Assuming that the script is completed (the above script does a simple print to the console) you need to deploy it to Lambda. For Python all you need to do is to zip your code and upload that to AWS Lambda. For PowerShell you need to call the “Publish-AWSPowerShellLambda” module passing in the script, a name for the Lambda function and the AWS region you want to have the function deployed to:
PS /home/dwe/Documents/aws/MyFirstPowershellLambda> Publish-AWSPowerShellLambda -ScriptPath ./MyFirstPowershellLambda.ps1 -Name MyFirstPowershellLambda -Region eu-central-1
… and this will fail with:
Get-Command: /home/dwe/.local/share/powershell/Modules/AWSLambdaPSCore/2.0.0.0/Private/_DeploymentFunctions.ps1:544 Line | 544 | $application = Get-Command -Name dotnet | ~~~~~~~~~~~~~~~~~~~~~~~~ | The term 'dotnet' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, | or if a path was included, verify that the path is correct and try again. Exception: /home/dwe/.local/share/powershell/Modules/AWSLambdaPSCore/2.0.0.0/Private/_DeploymentFunctions.ps1:547 Line | 547 | throw '.NET Core 3.1 SDK was not found which is required to b … | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | .NET Core 3.1 SDK was not found which is required to build the PowerShell Lambda package bundle. Download the .NET Core 3.1 SDK from | https://www.microsoft.com/net/download
The error message is quite clear: You need to install the “.NET Core 3.1 SDK” but as we added the Microsoft repositories above this is just a matter of (again, adjust for your package manager):
$ sudo apt-get install -y dotnet-sdk-3.1
Trying the same again and this time it succeeds:
PS /home/dwe/Documents/aws/MyFirstPowershellLambda> Publish-AWSPowerShellLambda -ScriptPath ./MyFirstPowershellLambda.ps1 -Name MyFirstPowershellLambda -Region eu-central-1 Staging deployment at /tmp/MyFirstPowershellLambda Configuring PowerShell to version 7.0.0 Generating C# project /tmp/MyFirstPowershellLambda/MyFirstPowershellLambda.csproj used to create Lambda function bundle. Generating /tmp/MyFirstPowershellLambda/Bootstrap.cs to load PowerShell script and required modules in Lambda environment. Generating aws-lambda-tools-defaults.json config file with default values used when publishing project. Copying PowerShell script to staging directory ... ... zipping: adding: Namotion.Reflection.dll (deflated 58%) ... zipping: adding: System.Diagnostics.PerformanceCounter.dll (deflated 60%) ... zipping: adding: MyFirstPowershellLambda.ps1 (deflated 53%) ... zipping: adding: System.Management.dll (deflated 62%) ... zipping: adding: Markdig.Signed.dll (deflated 62%) ... zipping: adding: libpsl-native.so (deflated 69%) ... Creating new Lambda function MyFirstPowershellLambda Enter name of the new IAM Role: dwe-tmp-role ... Select IAM Policy to attach to the new role and grant permissions 1) AWSLambdaFullAccess (Provides full access to Lambda, S3, DynamoDB, CloudWatch Metrics and ...) 2) AWSLambdaReplicator ... 1 Waiting for new IAM Role to propagate to AWS regions ............... Done New Lambda function created
Heading over to the AWS console we can see that the function is there:
Hope this helps…
L’article Publishing a PowerShell script to AWS Lambda est apparu en premier sur dbi Blog.