Ansible custom module (powershell): access environment variable - powershell

How can I access an environment variable in powershell when building a custom module?
- name: custom module
environment:
MY_ENVIRONMENT: "custom"
custom_action:
custom_param: "param"
register: result
With the following
Function Get-CommonSpec
{
#{
options = #{
MY_ENVIRONMENT = #{type = "str"; required = $true; }
}
}
}
I get 'missing required arguments USER' error

Related

Passing secure parameter to PowerShell DSC script from Bicep template

I am using a Bicep template to deploy a virtual machine with a PowerShell DSC script that adds a Log Analytics workspace to the Log Analytics agent. The script uses a secure parameter (workspaceKey1) which is defined in the template and pulled from a key vault. When running the script, I'm getting the following error:
" Performing the operation "Set-TargetResource" on target "Executing the SetScript with the user supplied credential"."},
PowerShell DSC resource MSFT_ScriptResource failed to execute Set-TargetResource functionality with error message: Value does not fall within the expected range."
A simplified version of the script is below.
Configuration MmaMultihoming
{
Param (
[string] $workspaceId1,
[System.Management.Automation.PSCredential] $workspaceKey1,
)
Import-DscResource -ModuleName PSDesiredStateConfiguration;
Import-DscResource -ModuleName xPSDesiredStateConfiguration;
[System.Management.Automation.PSCredential]$workspaceKey1 = New-Object System.Management.Automation.PSCredential ($workspaceKey1.userName, $workspaceKey1.password)
Node localhost {
Script ConfigureWorkspace
{
SetScript =
{
$workspaceId = $Using:workspaceId1;
$workspaceKey = $Using:workspaceKey1;
$mma = New-Object -ComObject 'AgentConfigManager.MgmtSvcCfg';
$mma.AddCloudWorkspace($workspaceId, $workspaceKey);
$mma.ReloadConfiguration();
}
TestScript = { Test-Path "HKLM:\SYSTEM\ControlSet001\Services\HealthService\Parameters\Service Connector Services\Log Analytics - $($Using:workspaceId)"}
GetScript = { #{ Result = (Get-ChildItem "HKLM:\SYSTEM\ControlSet001\Services\HealthService\Parameters\Service Connector Services")} }
}
}
}
The Bicep code is below:
param keyvaultName string = 'keyvault'
param kvResourceGroup string = 'keyvault-rg'
param workspaceId1 string
#secure()
param workspaceKey1 string = kv.getSecret('workspaceKey1')
resource kv 'Microsoft.KeyVault/vaults#2022-07-01' existing = {
name: keyvaultName
scope: resourceGroup(kvResourceGroup )
}
resource DSC_LogAnalytics 'Microsoft.Compute/virtualMachines/extensions#2022-08-01' = {
parent: vm1
name: 'Microsoft.Powershell.DSC'
location: location
properties: {
publisher: 'Microsoft.PowerShell'
type: 'DSC'
typeHandlerVersion: '2.77'
autoUpgradeMinorVersion: true
settings: {
wmfVersion: 'latest'
configuration: {
url: dscScript
script: 'dsc.ps1'
function: 'MmaMultihoming'
}
configurationArguments: {
workspaceId1: workspaceId1
}
privacy: {
datacollection: 'enable'
}
advancedOptions: {
forcePullAndApply: false
}
}
protectedSettings: {
configurationArguments: {
workspaceKey1: {
userName: 'donotuse'
password: workspaceKey1
}
}
configurationUrlSasToken: SaaStoken
}
}
}
I am really quite stuck so would appreciate any ideas people can give.
Thanks!

az cli/bicep targeted/single module deploys?

Is there an az/bicep equivalent to terraform apply -target=module.my_app.module.something?
Given a root bicep file:
module app '../../../projects/my/application/app.bicep' = {
name: 'app'
}
module test '../../../projects/my/application/test.bicep' = {
name: 'test'
}
module sample '../../../projects/my/application/sample.bicep' = {
name: 'sample'
params {
p1: 'p1'
}
}
Can I provision just the sample module somehow?
I could do something like: az deployment sub create --template-file ../../../projects/my/application/sample.bicep -l germanywestcentral
But this is not really the same thing, because this bypasses the params passed from the root module (which provides env separations) down to the actual module.
The command you have:
az deployment sub create --template-file ../../../projects/my/application/sample.bicep -l germanywestcentral will work just fine, you just pass the parameters you would normally pass to root.bicep that are needed by that module (e.g. p1)
If you have params that are created/manipulated in root.bicep you'd have to decide how you marshal those values manually.

Azure devops pass build parameters through Rest API

I'm trying to pass a parameters through the build rest API using jira, but it doesn't override the parameter.
Pipeline:
parameters:
- name: "Testplan"
type: string
default: "NoPlanDefined"
stage: Test
jobs:
- job: Testing_And_Transfer
- task: PowerShell#2
displayName: "Testing API Call"
inputs:
targetType: 'filepath'
filePath: './script/Jira.ps1'
arguments:
-Jira_id ${{ parameters.Testplan }}
Jira.ps1 content:
Param(
[string]$Jira_id = "no ID"
)
#-----------------------Jira API--------------------------
echo 'This is a test \n ID: '
echo $Jira_id
My rest command is setup like so:
URL: https://dev.azure.com/{My corp}/MyHello/_apis/build/builds?api-version=6.0
Body:
{
"definition": {
"id": 1
},
"parameters": "{ \"Testplan\":\"Postman\" }"
}
When using the trigger, the ps1 return NoPlanDefined as expected.
When using a manual trigger and changing the parameter, the parameter
get changed as expected.
When trying to change the parameter through
the Rest api, Testplan is empty instead of Postman.
I'm I doing something wrong with the REST API?
That's because those are not parameters, despite the name used in the REST call. They are run-time variables, which behave differently and are available at a different scope than parameters.
There is a different API that allows you to specify templateParameters: https://learn.microsoft.com/en-us/rest/api/azure/devops/pipelines/runs/run-pipeline?view=azure-devops-rest-6.1
If you are familiar with PowerShell you can use the AzurePipelinesPS module and the command below to pass parameters to pipelines when invoking them.
$id = '2' # your pipeline id
$templateParameters = #{
Testplan = 'myTestPlan' # your parameter and value
}
Invoke-APPipeline -Instance https://dev.azure.com -Collection 'yourCollectionName' -Project 'yourProjectName' -ApiVersion '6.0-preview.1' -PipelineId $id -TemplateParameters $templateParameters
The module supports "sessions" to limit the number of required parameters. See the module's github page on how to create a session.

How to pass a parameter to a powershell script in a jenkins pipeline

How do I pass my variable VAR_A to an embedded powershell script in a jenkins pipeline ?
e.g.
def VAR_A = 'test'
def mystatus = powershell(returnStatus: true, script: '''
Write-Host "My result: '$VAR_A'" '''
withEnv(["VAR_A=test"]) {
def mystatus = powershell(returnStatus: true, script: '''
Write-Host "My result: '$VAR_A'" '''
}
both result with following output
My result: ''
Note : I prefer to define my powershell script in the jenkinsfile to keep things simple.
Try this:
node {
powershell '''
$VAR_A = 'test'
Write-Host "My result: '$VAR_A'"
'''
withEnv(["VAR_A=envtest"]) {
powershell '''
Write-Host "My result is empty: '$VAR_A'"
Write-Host "My env result: '$env:VAR_A'"
'''
}
}
The output is:
My result: 'test'
My result is empty: ''
My env result: 'envtest'
This was tested on Jenkins 2.73.1.
Note that:
$VAR_A = 'test' is declared within the first powershell '''...'''
env: is required to access environment variables (see about_Environment_Variables in the Microsoft Docs)

DSC Script resource does not read environement variable

I have a DSC configuration which install nodejs, adds npm to environment Path variable and then installs a npm module.
xPackage InstallNodeJs {
Name = 'Node.js'
Path = "$env:SystemDrive\temp\node-v4.4.7-x64.msi"
ProductId = '8434AEA1-1294-47E3-9137-848F546CD824'
Arguments = "/quiet"
}
Environment AddEnvironmentPaths
{
Name = "Path"
Ensure = "Present"
Path = $true
Value = "$env:SystemDrive\ProgramData\npm"
}
Script UpgradeNpm {
SetScript = {
& npm install --global --production npm-windows-upgrade
& npm-windows-upgrade --npm-version 3.10.6
}
TestScript = {
$npmVersion = & npm -v
return $npmVersion -eq "3.10.6"
}
GetScript = {
return {#{Result = "UpgradeNpm"}}
}
}
Installing nodejs and adding npm to Path variable seems to be successful. Both nodejs and npm location are added to Path and I can use them both in powershell and cmd.
However, Script resource returns that 'npm' is not recognized as internal or external command ...
the same is for node which is used inside npm-windows-upgrade script file.
Do you know why Script resource cannot read newly added Path entires?
The Environment DSC resource implementation makes the change by updating the values stored in the registry (with the exception of variables targeting Process). Changes made to environment variables stored in the registry are not reflected in the current session (read once, on session start).
You can affect values stored in the current session by:
Using System.Environment.SetEnvironmentVariable ([System.Environment]::SetEnvironmentVariable)
Modifying $env:<VariableName>
Of those, only the first allows you to write a persistent change. The latter can be considered a volatile change.
It's an odd limitation of the resource, I've looked at this before and felt it a little lacking.
There's no dependency information in there, so you can't count on the Environment resource running before the Script resource. There's not enough information in your post to tell if that's the case for sure, but you should consider controlling it anyway:
xPackage InstallNodeJs {
Name = 'Node.js'
Path = "$env:SystemDrive\temp\node-v4.4.7-x64.msi"
ProductId = '8434AEA1-1294-47E3-9137-848F546CD824'
Arguments = "/quiet"
}
Environment AddEnvironmentPaths
{
Name = "Path"
Ensure = "Present"
Path = $true
Value = "$env:SystemDrive\ProgramData\npm"
DependsOn = '[xPackage]InstallNodeJs'
}
Script UpgradeNpm {
SetScript = {
& npm install --global --production npm-windows-upgrade
& npm-windows-upgrade --npm-version 3.10.6
}
TestScript = {
$npmVersion = & npm -v
return $npmVersion -eq "3.10.6"
}
GetScript = {
return {#{Result = "UpgradeNpm"}}
}
DependsOn = '[Environment]AddEnvironmentPaths'
}
Can you share which version of DSC you are using? You can get this by doing a $PSVersionTable on the PowerShell console. I am able to add to the PATH variable and use it in a script resource.
configuration NPMTest
{
Environment AddEnvironmentPaths
{
Name = 'Path'
Ensure = 'Present'
Path = $true
Value = "$env:SystemDrive\ProgramData\npm"
}
Script p
{
GetScript = {#{}}
TestScript = {return $false}
SetScript = {$a = & a.ps1 ; Write-Verbose $a -Verbose}
}
}
The script a.ps1 was executed fine even though I am not specifying the full path to the script.