As the tile said, i would like to know the way to use this Get-AnsibleParam function. More specific, how to apply Get-AnsibleParam in this case:
i have a YAML file that contained some variables
---
type: taskWindows
actions:
abortActions: []
emailNotifications: []
setVariableActions: []
snmpNotifications: []
systemOperations: []
agent: test
name: "Test"
summary: "Test"
...
I have a Powershell Script:
function Stonebrach.Connect {
param(
[Parameter(Mandatory=$true)]
$Sb_uri,
[Parameter(Mandatory=$true)]
$Auth_filename,
[Parameter(Mandatory=$true)]
$Method,
[Parameter(Mandatory=$false)]
$Body
)
$basicAuth=Get-Content "C:\$auth_filename"
$headers = #{
"Authorization" = $basicAuth
"Content-Type"="application/json"
}
$RSP=$null
try{
if ( $body -eq $null ) {
$response = invoke-restmethod -Uri $Sb_uri -Method $Method -Headers $headers
}
else {
$response = invoke-restmethod -Uri $sb_uri -Method $method -Headers $headers -Body **$body**
}
return $response
}
catch{
$RSP = $_.Exception.Message
return $RSP
}
}
function Stonebranch.Create.Task.Windows {
param(
[Parameter(Mandatory=$true)]
$Sb_base_uri,
[Parameter(Mandatory=$true)]
$Auth_filename,
[Parameter(Mandatory=$true)]
$Method,
[Parameter(Mandatory=$true)]
$Body
)
Stonebrach.Connect -SB_uri $Sb_base_uri/task -Auth_filename
$Auth_filename -Method $Method -Body $Body
}
Can i use Get-AnsibleParam to get the variables from YAML file (all of them) into the $body in the PS script in this case? I tried to read the documentation, but it is not very clear how to use the function:
https://code.vt.edu/nis-ansible-roles/upstream-ansible/blob/2a751e1753c1fe675ba3d0b1dbc9939c9253ea70/lib/ansible/module_utils/powershell.ps1
Please help. Thanks
Get-AnsibleParam is used to access specific parameter passed to a module. You can't use it to get all variables from your playbooks.
Take a look at win_ping for example usage:
$params = Parse-Args $args -supports_check_mode $true
$data = Get-AnsibleParam -obj $params -name "data" -type "str" -default "pong"
if ($data -eq "crash") {
throw "boom"
}
In this case win_ping can accept parameter named data of type string with default value pong.
Related
I am trying to create a user story and task in Azure DevOps with this RESTapi
There are multiple backlogs.
POST https://dev.azure.com/{organization}/{project}/_apis/wit/workitems/${type}?api-version=6.0
My code
function Set-pbiStuff {
param
(
[Parameter(Mandatory = $true)] [string] $Organization,
[Parameter(Mandatory = $true)] [string] $Project,
[Parameter(Mandatory = $true)] [hashtable] $Token
)
$Base = "https://dev.azure.com/$($organization)/$($project)/_apis/wit/workitems"
$workItemType = 'task'
$URL = "$($Base)/$($workItemType)?api-version=6.0"
$Json = #(
#{
op = 'add'
path = '/fields/System.Title'
value = $workItemType
}
)
$Body = (ConvertTo-Json $Json)
$response = Invoke-RestMethod `
-Method Post `
-Uri $URL `
-ContentType 'application/json' `
-Body $Body `
-Headers $Token
Write-Host $URL
Write-Host $response
}
$Token= #{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($env:SYSTEM_ACCESSTOKEN)")) }
$tt = Set-pbiStuff -Organization 'myOrganization' -Project 'myProject' -Token $Token
return $tt
But the response I get is that the page was not found.
What have I missed?
The problem is that the type ${type} is incorrect in your script, the character $ is missing.
Please try this:
$URL = "$($Base)/"+"$"+"$($workItemType)?api-version=6.0"
And the content type should be "application/json-patch+json"
Below script works for me : (PAT used for the test, you can change it back to SYSTEM_ACCESSTOKEN if you run it in pipeline)
function Set-pbiStuff {
param
(
[Parameter(Mandatory = $true)] [string] $Organization ,
[Parameter(Mandatory = $true)] [string] $Project ,
[Parameter(Mandatory = $true)] [string] $Token
)
$Base = "https://dev.azure.com/$($organization)/$($project)/_apis/wit/workitems"
$workItemType = 'task'
$URL = "$($Base)/"+"$"+"$($workItemType)?api-version=6.0"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f '',$Token)))
$Json = #(
#{
op = 'add'
path = '/fields/System.Title'
value = $workItemType
}
)
$Body = (ConvertTo-Json $Json)
$response = Invoke-RestMethod `
-Method Post `
-Uri $URL `
-ContentType 'application/json-patch+json' `
-Body $Body `
-Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)}
Write-Host $URL
Write-Host $response
}
$tt = Set-pbiStuff -Organization 'orgname' -Project 'ProjectName' -Token Tokenhere
return $tt
You're trying to call the API with a PATCH verb, see line two:
$response = Invoke-RestMethod `
-Method Patch `
-Uri $URL `
-ContentType 'application/json' `
-Body $Body `
-Headers $AzAuthHeader
The API endpoint is, like the documentation shows and you stated in your question, a POST endpoint.
Try this URL:
$URL = "$($Base)/`$$($workItemType)?api-version=6.0"
Check this sample: https://arindamhazra.com/create-azure-devops-task-using-powershell/
I have a powershell script with 2 funtions:
function Stonebrach.Connect {
param(
[Parameter(Mandatory=$true)]
$Sb_uri,
[Parameter(Mandatory=$true)]
$Auth_filename,
[Parameter(Mandatory=$true)]
$Method,
[Parameter(Mandatory=$false)]
$Body
)
$basicAuth=Get-Content "C:\$auth_filename"
$headers = #{
"Authorization" = $basicAuth
"Content-Type"="application/json"
}
$RSP=$null
try{
if ( $body -eq $null ) {
$response = invoke-restmethod -Uri $Sb_uri -Method $Method -Headers $headers
}
else {
$response = invoke-restmethod -Uri $sb_uri -Method $method -Headers $headers -Body $body
}
return $response
}
catch{
$RSP = $_.Exception.Message
return $RSP
}
}
function Stonebranch.Create.Task.Windows {
param(
[Parameter(Mandatory=$true)]
$Sb_base_uri,
[Parameter(Mandatory=$true)]
$Auth_filename,
[Parameter(Mandatory=$true)]
$Method,
[Parameter(Mandatory=$true)]
$Body
)
Stonebrach.Connect -SB_uri $Sb_base_uri/task -Auth_filename $Auth_filename -Method $Method -Body $Body
}
the body param is hardcoded as below:
$body = '
{
"type" : "taskWindows",
"actions" : {
"abortActions" : [],
"emailNotifications" : [],
"setVariableActions" : [],
"snmpNotifications" : [],
"systemOperations" : []
},
"agent" : "test",
"name" : "Test Create",
"summary" : "Test Create"
}
'
Call the function:
$response = Stonebranch.Create.Task.Windows -Sb_base_uri $Sb_base_uri -Auth_filename $Auth_filename -Method POST -Body $body
Here's the question: i want to separate the $body into a different file (prefer YAML file). Anyone know how to separate and pass the list of param to the script so i can use them? I find it hard to pass the list of param and call the function.
Please help me, thanks.
I'm using the following to send to single recipient, and single Cc recipient.
How do I send to multiple recipients, either in To: and/or Cc: ?
Thanks! I have tried all different combinations but its still not working (still getting as if its no surprise, the usual Invoke-RestMethod :The remote server returned an error: (400) Bad Request.)
[CmdletBinding()]
param(
[Parameter(Mandatory=$True,
ValueFromPipeline=$True,
HelpMessage="Email Address e.g man1#whatever.com")]
[Alias('Email')]
$Subject,
$Content)
UserName = "myUPN#mywork.com"
$Password = cat C:\Creds\mycreds.txt | convertto-securestring
$cred = new-object -typename System.Management.Automation.PSCredential -
argumentlist $username,$password
$contentType = "application/json;odata.metadata=full"
$uri = "https://outlook.office365.com/api/v1.0/me/sendmail"
$body = "{
""Message"":{
""Subject"": ""$Subject"",
""Importance"": ""High"",
""Body"": {
""ContentType"": ""HTML"",
""Content"": ""$Content""
},
""ToRecipients"": [
{
""EmailAddress"":{
""Address"": ""man1#whateverdomain.com""
}
}
],
""CcRecipients"": [
{
""EmailAddress"":{
""Address"": ""man2#whateverdomain.com""
}
}
]
}}"
Invoke-RestMethod -Uri $uri -Method Post -Credential $cred`
-Body $Body -ContentType $contentType
You can specify the CC's with an array to feed into this
[CmdletBinding()]
param(
[Parameter(Mandatory=$True,
ValueFromPipeline=$True,
HelpMessage="Email Address e.g man.man#domain.com")]
[Alias('Email')]
$EmailAddress,
$CCEmailAddress,
$Subject,
$Content)
$UserName = "man.man#domain.com"
$Password = cat C:\Creds\regcreds.txt | convertto-securestring
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username,$password
$CCinJSON = $CCEmailAddress | %{'{"EmailAddress": {"Address": "'+$_+'"}},'}
$CCinJSON = ([string]$CCinJSON).Substring(0, ([string]$CCinJSON).Length - 1)
$contentType = "application/json;odata.metadata=full"
$uri = "https://outlook.office365.com/api/v1.0/me/sendmail"
$body = "{
""Message"":{
""Subject"": ""$Subject"",
""Importance"": ""High"",
""Body"": {
""ContentType"": ""HTML"",
""Content"": ""$Content""
},
""ToRecipients"": [
{
""EmailAddress"":{
""Address"": ""$EmailAddress""
}
}
],
""CcRecipients"": [
$CCinJSON
]
}}"
echo $body
Invoke-RestMethod -Uri $uri -Method Post -Credential $cred -Body $Body -ContentType $contentType
I am trying to create build configurations via the restapi and powershell and keep getting the following error:
Exception calling "GetResponse" with "0" argument(s): "The remote server returned an error: (405) Method Not Allowed."
It seems that I can use GET fine, the issue appears to be with the PUT command
Code Snippet
$url = http://%teamcityServer%:8111/app/rest/buildTypes/id:%projectname%"
$req = [System.Net.WebRequest]::Create($url)
$req.ContentType = "text/plain"
$req.UseDefaultCredentials = $true
$req.Credentials = Get-Credential("username")
$req.Method ="PUT"
$req.ContentLength = 0
$req.Accept = "*/*"
$resp = $req.GetResponse()
$results = [xml]$resp.ReadToEnd()
Output from the Team City log
2015-09-10 09:14:30,582] WARN [io-8111-exec-70] - est.jersey.ExceptionMapperUtil - Error has occurred during request processing (405). Error: javax.ws.rs.WebApplicationException. Not supported request. Please check URL, HTTP method and transfered data are correct. metadata: [Allow:[HEAD,DELETE,GET,OPTIONS],] Request: PUT '/app/rest/buildTypes/id:%project%'
Team City Version is 9.1.1 so I believe this is possible.
I'm fairly new to the restapi so any input is appreciated.
Its possible but you need to post xml data to create builds/projects. For example if you need to create a project you can POST XML something like
<newProjectDescription name='New Project Name' id='newProjectId' copyAllAssociatedSettings='true'><parentProject locator='id:project1'/><sourceProject locator='id:project2'/></newProjectDescription>
to http://teamcity:8111/httpAuth/app/rest/projects.
Check more info on Teamcity REST documentation.
You didn't mention your powershell version, but if you are using 3.0 or later you can call Invoke-WebRequest cmdlet and your code should look something like:
Invoke-WebRequest -Uri $uri -Credential $cred -Method Post -Body $body -ContentType "Application/xml"
For PowerShell 2.0 You can write your own Web-Request method like:
function Web-Request{
param(
[Parameter(Mandatory=$true)]
[string]
$Uri,
[Parameter(Mandatory=$false)]
[string]
$Username = $null,
[Parameter(Mandatory=$false)]
[string]
$Password = $null,
[Parameter(Mandatory=$true)]
[string]
$ContentType,
[Parameter(Mandatory=$true)]
[string]
$Method,
[Parameter(Mandatory=$false)]
[string]
$PostString
)
$webRequest = [System.Net.WebRequest]::Create($Uri)
$webRequest.ContentType = $ContentType
$webRequest.Method = $Method
$webRequest.Accept = "*/*"
if ($Username)
{
$webRequest.Credentials = new-object system.net.networkcredential($Username, $Password)
}
try
{
switch -regex ($Method)
{
"PUT|POST" # PUT and POST behaves similar ways except that POST is only used for creation while PUT for creation/modification
{
if ($PostString -ne "")
{
$PostStringBytes = [System.Text.Encoding]::UTF8.GetBytes($PostString)
$webrequest.ContentLength = $PostStringBytes.Length
$requestStream = $webRequest.GetRequestStream()
$requestStream.Write($PostStringBytes, 0,$PostStringBytes.length)
}
else
{
$requestStream = $webRequest.GetRequestStream()
}
}
"DELETE"
{
$requestStream = $webRequest.GetRequestStream()
}
default
{
# GET requests usually don't have bodies, default will behave like a GET
}
}
if ($requestStream -ne $null)
{
$requestStream.Close()
}
[System.Net.WebResponse] $resp = $webRequest.GetResponse();
$rs = $resp.GetResponseStream();
[System.IO.StreamReader] $sr = New-Object System.IO.StreamReader -argumentList $rs;
[string] $results = $sr.ReadToEnd();
}
catch
{
$results = "Error : $_.Exception.Message"
}
finally
{
if ($sr -ne $null) { $sr.Close(); }
if ($resp -ne $null) { $resp.Close(); }
$resp = $null;
$webRequest = $null;
$sr = $null;
$requestStream = $null;
}
return $results
}
What I am currently doing:
Invoke-WebRequest -Uri https://coolWebsite.com/ext/ext -ContentType application/json -Method POST -Body $someJSONFile
I am looking for a way to POST this same .json file in Powershell without using Invoke-WebRequest, if it is possible. This new method would preferably allow me to get the server output content and parse through it in powershell.
Maybe by calling an outside cURL method? I really am not sure and all my internet research has proved fruitless.
How can I achieve this above result without Invoke-WebRequest?
You can try this :
# RestRequest.ps1
Add-Type -AssemblyName System.ServiceModel.Web, System.Runtime.Serialization, System.Web.Extensions
$utf8 = [System.Text.Encoding]::UTF8
function Request-Rest
{
[CmdletBinding()]
PARAM (
[Parameter(Mandatory=$true)]
[String] $URL,
[Parameter(Mandatory=$false)]
[System.Net.NetworkCredential] $credentials,
[Parameter(Mandatory=$true)]
[String] $JSON)
# Remove NewLine from json
$JSON = $JSON -replace "$([Environment]::NewLine) *",""
# Create a URL instance since the HttpWebRequest.Create Method will escape the URL by default.
# $URL = Fix-Url $Url
$URI = New-Object System.Uri($URL,$true)
try
{
# Create a request object using the URI
$request = [System.Net.HttpWebRequest]::Create($URI)
# Build up a nice User Agent
$UserAgent = "My user Agent"
$request.UserAgent = $("{0} (PowerShell {1}; .NET CLR {2}; {3})" -f $UserAgent, $(if($Host.Version){$Host.Version}else{"1.0"}),
[Environment]::Version,
[Environment]::OSVersion.ToString().Replace("Microsoft Windows ", "Win"))
$request.Credentials = $credentials
$request.KeepAlive = $true
$request.Pipelined = $true
$request.AllowAutoRedirect = $false
$request.Method = "POST"
$request.ContentType = "application/json"
$request.Accept = "application/json"
$utf8Bytes = [System.Text.Encoding]::UTF8.GetBytes($JSON)
$request.ContentLength = $utf8Bytes.Length
$postStream = $request.GetRequestStream()
$postStream.Write($utf8Bytes, 0, $utf8Bytes.Length)
#Write-String -stream $postStream -string $JSON
$postStream.Dispose()
try
{
#[System.Net.HttpWebResponse] $response = [System.Net.HttpWebResponse] $request.GetResponse()
$response = $request.GetResponse()
}
catch
{
$response = $Error[0].Exception.InnerException.Response;
Throw "Exception occurred in $($MyInvocation.MyCommand): `n$($_.Exception.Message)"
}
$reader = [IO.StreamReader] $response.GetResponseStream()
$output = $reader.ReadToEnd()
$reader.Close()
$response.Close()
Write-Output $output
}
catch
{
$output = #"
{
"error":1,
"error_desc":"Error : Problème d'accès au serveur $($_.Exception.Message)"
}
"#
Write-Output $output
}
}
Edited 19-10-2015
Here is an example usage :
#$urlBase = "http://192.168.1.1:8080/"
#######################################################################
# Login #
#######################################################################
$wsLogin = "production/login"
Function login
{
[CmdletBinding()]
PARAM
(
[ValidateNotNullOrEmpty()]
[String] $login,
[String] $passwd
)
Write-Verbose $wsLogin
#$jsonIn = [PSCustomObject]#{"login"=$login;"passwd"=$passwd} | ConvertTo-Json
$jsonIn = #"
{
"login":"$login",
"passwd":"$passwd"
}
"#
Write-Verbose $jsonIn
$jsonOut = Request-Rest -URL "$urlBase$wsLogin" -JSON $jsonIn -credentials $null
Write-Verbose $jsonOut
#return $jsonOut | ConvertFrom-Json
return $jsonOut
}
It is easy to convert that code to cURL
curl -v --insecure -X POST -H "Content-Type: application/json" --data-binary someJSONFile.js https://coolWebsite.com/ext/ext/