Posted on Leave a comment

Create a confluence page with REST API

Confluence can become a great tool when it is combined with other services that we use. In some cases tho you cannot find an available integration but there comes the rest api that you can use.

https://developer.atlassian.com/server/confluence/confluence-rest-api-examples/

In this example we will automatically create a confluence page from another service using a rest API. In this example I was working on a custom confluence installation and not jira cloud. When using Jira Cloud the API can be different.

Using the link from confluence documentation you can locate any actions that you need to perform. Lets take as example the creation of a sub-page inside an existing page. You can find the curl API call below.

curl -X POST -H 'Content-Type: application/json' -H 'Authorization: Bearer TOKEN' -d '{"type":"page","title":"test incident","ancestors":[{"id":pageID}], "space":{"key":"dd"},"body":{"storage":{"value":"<p>This is a new page</p>","representation":"storage"}}}' https://confluence.domain.com/rest/api/content/

Description:

TOKEN: You should create a personal access token for a user with the rights to open/create/edit a page. You can use also username and password authentication with parameter -u user:password.
Title: the title of your new sub-page
Ancestors: The parent page under which to create a new page.
Space Key: your confluence space where you will create the page.
Body: you should keep the json format and pass the content you need to appear on the page body.
URL: you should use the url of the REST API. Just change the domain name and it will work on v7.18+

When we make the request we can see that a new page is created with the title that we provided.

Posted on 2 Comments

Run powershell command on virtual machines scale set

Azure Virtual Machine Scale Sets let you create and manage a group of load balanced VMs. The number of VM instances can automatically increase or decrease in response to demand or a defined schedule. Scale sets are commonly used for critical infrastructure like Kubernetes and service fabric. In this guide we will examine how we can perform an action massively on all nodes of the vmss.

The below vmss is composed of windows virtual machines that belong to an azure resource.

When you need to update all the nodes of vmss with a specific action, for instance to install a powershell module, you will need to use the run-command.

az vmss run-command | Microsoft Learn

First you will need to get all instances ids as they are a parameter for the next commands.

az vmss list-instances -n $vmss_name -g $rg_name --query "[].id" --output tsv

The output should be similar with the below.

/subscriptions/ID/resourceGroups/rg/providers/Microsoft.Compute/virtualMachineScaleSets/vmssname/virtualMachines/0
/subscriptions/ID/resourceGroups/rg/providers/Microsoft.Compute/virtualMachineScaleSets/vmssname/virtualMachines/1
/subscriptions/ID/resourceGroups/rg/providers/Microsoft.Compute/virtualMachineScaleSets/vmssname/virtualMachines/2

Then you can execute a powershell script on the vmss nodes by specifying the node id of the previous command and the resource group name along with the vmss name.

az vmss run-command invoke  --command-id RunPowerShellScript -n $vmss_name -g $rg_name --scripts 'hostname' --instance-id 0

Youtube video:

Posted on Leave a comment

Multi threading in powershell

Multi threading can save you a lot of time when you process multiple multiple jobs at the same time. Powershell is a very advanced scripting tool and there are a lot of things that can be implemented with it. As a result in many occasions you will need to do things in parallel so that you have a quicker execution.

Lets examine a simple scenario on how we can use multi threading on powershell. We will use the Test-Connection method which sends ICMP echo request packets, or pings, to one or more computers. We will use the below three domains and we will try to execute a test connection to all of them.

$computers = @("google.gr","microsoft.com","facebook.com")

In order to calculate the time that this operation needs we will use the StopWatch class.

$watch = New-Object System.Diagnostics.Stopwatch; 
$watch.Start(); 
foreach ($item in $computers) { test-connection $item; }; 
echo "Elapsed time:" $watch.Elapsed.TotalSeconds;

The total Elapsed Time for this operation to complete would be around 10 seconds by performing the actions serially.

Lets examine how could we could use multi threading in order to complete this operation faster. In powershell v7 you can use the ForEach-Object with Parallel parameter. An example can be found below. This operation will be executed in parallel by multiple threads.

$watch = New-Object System.Diagnostics.Stopwatch;  
$watch.Start(); 
$computers | ForEach-Object -Parallel {test-connection $_} -AsJob | Receive-Job -Wait ; 
echo "Elapsed time:" $watch.Elapsed.TotalSeconds;

The result for this execution would be 3.8 seconds which means that we have 6 seconds less execution time or about 2.5 times faster.

If we use powershell v5 we can implement multi threading with the Start-Job. By using that we will need to write our logic inside the ScriptBlock.

$watch = New-Object System.Diagnostics.Stopwatch; 
$watch.Start(); 
$job1 = Start-Job -ScriptBlock { test-connection -ComputerName "google.gr" }
$job2 = Start-Job -ScriptBlock { test-connection -ComputerName "microsoft.com" }
$job3 = Start-Job -ScriptBlock { test-connection -ComputerName "facebook.com" }

Get-Job | Wait-Job

Receive-Job $job1
Receive-Job $job2
Receive-Job $job3

echo "Elapsed time:" $watch.Elapsed.TotalSeconds;

As we can see the execution time is about 3,9 seconds which is close enough with the time of powershell 7 script.

Youtube video:

Posted on Leave a comment

Get standard error output from command on powershell

There could be times that you will need to get the standard output from a script or command in powershell and handle this information. An example that I use is the output of docker info which I use to monitor the service state along with other things. The output of the docker info will inform you about an error during connection if the engine is not working. In the latest version of docker they changed the way message is displayed and this information will be printed on standard error instead of standard output.

docker info

As a result when you try to find the connection state through a powershell command you will fail identifying the correct state.

 (docker info).Contains('ERROR: error during connect')

This behavior is noticed because the error is printed on standard error.

In order to bypass and get the standard error on the output, you will need to use 2>&1 along with the command.

docker info 2>&1 

After that you can handle the output message appropriately.