Copy Files/Directories using Robocopy with Powershell

I have worked on some repetitive works which involves copying files between some servers. I always try to automate as it reduce the manual errors and I am lazy to do boring task in manual :).

Using powershells Copy-Item is simple and straight forward. But Robocopy provides more features. It provides many options like retry/jobs/filtering/mirroring which I use mostly when working.

We can get the all supported parameters from Robocopy documentation or simple running robocopy /? in command line.

$source = '<SOURCE_PATH>'
$destination = '<DESTINATION_PATH>'
# /E - Copies subdirectories. This option automatically includes empty directories. Refer the doc for supported parameters
$robocopyOptions = @('/E')

Write-Host 'Copying from $source to $destination'

$CmdLine = @($source, $destination) + $robocopyOptions
& 'robocopy.exe' $CmdLine

Write-Host 'Copy Completed'

Preceding command invokes Robocopy windows utility and copy the files. This is the simplest usage and we can use it for more complex scenarios.

Read and Write/Update the XML file in Powershell

In many cases, we found ourselves in a situation where we need to Read and update XML files.

It’s quite straight forward in Power Shell.

Sample XML File:Β 

Powershell script to read and update XML file

<App>
<Secret></Secret>
</App>
view raw sample.xml hosted with ❤ by GitHub

Powershell script to read and write XML file

$xmlFileName "Path to XML File";
[xml]$xmlDoc = Get-Content $xmlFileName
$xmlDoc.APP.Secret = "Some Value"
$xmlDoc.Save($xmlFileName)

The “Using” Statement In Powershell

When we do code in c#, we have using statement to dispose our objects. so we don’t have to. :).Β  What about PowerShell? Can we do that?

Here is a PowerShell function which behaves as using statement. πŸ™‚


Function Using-Object(
[System.IDisposable]
$InputObject,
[scriptblock]
$ScriptBlock = {throw "ScriptBlock is mandatory, please provide a value."})
{
try
{
. $ScriptBlock
}
finally
{
if ($null -ne $InputObject -and $InputObject -is [System.IDisposable])
{
$InputObject.Dispose()
}
}
}

So whenever we are dealing with an object that should be disposed we can use this function as below.


# $Connection object will be diposed.
Using-Object($Connection = New-Object System.Data.SQLClient.SQLConnection($ConnectionString)) {
#code goes here.
}

view raw

using-using.ps1

hosted with ❤ by GitHub

Isn’t that cool? πŸ™‚

Create Service Principal using Powershell and Login to Azure with Powershell

What is Service principle?

Service principle are non-interactive Azure accounts.Β  Applications use Azure services should always have restricted permissions.Β  Azure offers Service principals allow applications to login with restricted permission Instead having full privilege in non-interactive way.

Using Service Principal we can control which resources can be accessed.

For Security reason, it’s always recommended to use service principal with automated tools rather than allowing them to log in with user identity

Create a Service Principal with PowerShell.Β 

Note: For this demo we are using Azure RM PowerShell module. Azure has introduced new PowerShell module called AZ. Create AD App

Create AD app

#Create Service principal
New-AzureRmADServicePrincipal -ApplicationId $app.ApplicationId `
-DisplayName $dummyUrl `
-Password $securePassword `
-Scope "/subscriptions/<SUBSCRIPTION ID>" `
-Role Contributor `
-StartDate ([datetime]::Now) `
-EndDate $([datetime]::now.AddYears(1)) -Verbose

Create a Service Principal

#Create Service principal
New-AzureRmADServicePrincipal -ApplicationId $app.ApplicationId `
-DisplayName $dummyUrl `
-Password $securePassword `
-Scope "/subscriptions/<SUBSCRIPTION ID>" `
-Role Contributor `
-StartDate ([datetime]::Now) `
-EndDate $([datetime]::now.AddYears(1)) -Verbose

This service principal is valid for one year from the created date and it has Contributor Role assigned. Further using this Service principal application can access resource under given subscription.Β  We can scope to resources as we wish by passing resource id as a parameter for Scope.

View created AD app in Portal

Β Β  1. Log in Portal

  • Go to Azure Active Direcoty -> App Registrations
  • We can find the created app as below
  • Once we click the app we will see app details as below

We need this information when we need to login through Service principal

Login using Service Principal with Powershell

#Login with service principal
$clientId = "<CLIENT ID>"
$credentials = New-Object System.Management.Automation.PSCredential ($clientId, $securePassword)
Login-AzureRmAccount -ServicePrincipal -TenantId "<TENANTID>" `
-SubscriptionId "<SUBSCRIPTIONID>" `
-Credential $credentials

Fill out the required parameters.

Once we run the script we can successfully log in to Azure using Service Principal

Full code: πŸ™‚

#Create AD app
$dummyUrl = "https://dummy.dummy.com&quot;
$passpowrd = "Qwerty@123!"
$securePassword = ConvertTo-SecureString -String $passpowrd -AsPlainText -Force
$app = New-AzureRmADApplication -DisplayName $dummyUrl `
-IdentifierUris $dummyUrl `
-HomePage $dummyUrl `
-Password $securePassword -Verbose
#Create Service principal
New-AzureRmADServicePrincipal -ApplicationId $app.ApplicationId `
-DisplayName $dummyUrl `
-Password $securePassword `
-Scope "/subscriptions/<SUBSCRIPTION ID>" `
-Role Contributor `
-StartDate ([datetime]::Now) `
-EndDate $([datetime]::now.AddYears(1)) -Verbose
#Login with service principal
$clientId = "<CLIENT ID>"
$credentials = New-Object System.Management.Automation.PSCredential ($clientId, $securePassword)
Login-AzureRmAccount -ServicePrincipal -TenantId "<TENANTID>" `
-SubscriptionId "<SUBSCRIPTIONID>" `
-Credential $credentials

Β 

 

Powershell Identify whether running on Administrator

In some cases, we need to run some script in administrator mode.

Sometimes we face a situation where we want to know whether the script is running on Administrator mode.

Following script says whether PowerShell script is running on Administrator mode or not.


$elevated = [bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).groups -match "S-1-5-32-544")
if($elevated -eq $false)
{
throw "In order to install services, please run this script elevated."
}
else {
Write-Host "You are in Administrator mode"
}

πŸ™‚

Calling POST REST API in powershell with headers

In some cases we need to call POST REST API using Powershell.

Let’s go through sample code to get to know how it is done using Powershell.

In this Article we will go through below topics.

  • Create sample Web API
  • Invoke Web API in Powershell

Create Sample Web API

  1. Create ASP.NET Core Web Application

  1. Select API option

  1. Once project created we can see default values controller as below

We need our API to accept some Data. So we will create Modal class for that

  1. Create Modals Folder

  1. Create SampleData class under Modals Folder

  1. Add Sample properties to the class. I created Value1 and Value2 as string type.

  1. Implement API method in ValuesController as below.
[Route(“TestMethod”)]
[HttpPost]
public ActionResult TestMethod(SampleData data)
{
// Do what ever with Data
var authKey = Request.Headers[“AuthKey”];return Ok();

}

Invoke Web API in Powershell

  1. Open Powershell ISE and write following codes to invoke REST API.

 

  • Api url
$apiUri = “https://localhost:44326/api/values/TestMethod&#8221;
  • POST Body Data Object

 

$data = @{
‘Value1’ = “val1”
‘Value2’ = “val2”
}
  • Convert POST BODY data to json format
$requestBody = $data | ConvertTo-Json -Compress
  • Create request headers object
$requestHeaders = @{‘AuthKey’ = ‘sampleauth’}
  • Use Powershell Invoke-RestMethod with parameter as below
Invoke-RestMethod -Method Post -Uri $apiUri -Body $requestBody -ContentType “application/json” -Headers $requestHeaders
  1. Put break point on TestMethod and Run the API project in debug mode
  2. Run the Powershell snippet in Powershell ISE

  1. Breakpoint will be hit and we can see the data we passed.

  1. Once you step over to β€œauthkey” line we can see β€œAuthKey” header value

 

So this is how we call POST REST API end point in Powershell. ☺

Reading json file and update json file in powershell

There are some cases we need to update json files using powershell.

This is how I do it.


$filePath = "C:\jeevan\sample.json"
$file = ([System.IO.File]::ReadAllText($filePath) | ConvertFrom-Json)
Write-Host $file.property1
$file.property1 = Get-Random
$file | ConvertTo-Json | Out-File -FilePath $filePath -Encoding utf8 -Force

1

I used following json file


{
"property1": 123,
"property2": "value2"
}

view raw

sample.json

hosted with ❤ by GitHub

Done πŸ™‚