A bit of powershell and Azure magic


 After a long hiatus where volume of work has juts left me with no desire to spend extra effort writing things up on here I've finally put pen to paper (well technically hands to keyboard).

There have been so many things I could have written about recently and In some ways I wish I had (mainly selfishly as I often refer back to my own notes.....) but this Is a good one and covers a few things that others will find useful - even those outside of Azure for part of this one.

So this is the problem statement (and there are likely many ways to solve this - but this method has some useful tricks worth sharing).

I want to make a file appear on the desktop of a remote windows 10 device in Azure, this file needs to contain some PowerShell code to do 'something' on the device (actual content not important) - but it should be as simple as possible for the end user - i.e. they are non technical

I have some limitations at the point - the main one being is that I'm running the script against a machine that is not AD joined (it's AAD joined) and I don't know Intune or have any access to mess around with it anyway. So that rules out a couple of traditional approaches. It also (for reasons I won't go into) has to be run explicitly by the end user and can't just be fully automated.

In the end I decided there were two distinct technical things to resolve

1. How to make it easy for the end user?

2. How to get the solution to the end user?

I'll start (as is normal) with the first point - giving this some thought the only way to make this really simple for an end user is just to make it something you can double click. Powershell can sometimes just run OK when double clicked but is often subject to what has been allowed by policy and is also likely to open in the wrong program if file extension mappings are wrong. I wanted to avoid anything that would result in confusion and then questions back to the support team.

So how to deal with that? Well usefully on a PowerShell course I attended a couple of years back I was told about a simple utility that can convert PowerShell scripts into executables - there is even a simple GUI utility for that

https://gallery.technet.microsoft.com/scriptcenter/PS2EXE-GUI-Convert-e7cb69d5

Opening that up you see this simple interface where you give it your input PowerShell file and define some things for output - see pic below


So in my case c:\temp.ps1 is the input file and I want to generate an executable called adduser.exe and also add some metadata to that file of version number, product name and description.

So clicking compile and now I have adduser.exe that I can just double click and it performs the same job as the PowerShell script without the PowerShell - so easy for end users.

So job number 1 ticked off - nice and easy

Now on to the second point - how to get the file transferred over to the virtual machine?

First thing we need to do is put the file somewhere it can be reached - easiest way is to just put it into a storage account where it can pulled from.

I'll assume you know how to do that as it's a very common thing to want to do - the end result is the file ends up in a location like this  

https://somestorageaccount.blob.core.windows.net/adduser/adduser.exe

Now i just have to execute some code to remotely pull the file down to the machine - again I can do this with some simple PowerShell making use of the relevant Azure cmdlets to run things on remote machines

The end result being a short bit of code (shown below) that connects to the rights subscription, generates a file to execute locally (as you cant just type the powershell commands in direct here) then runs that on the remote machine.

set-azcontext -Subscription SUBSCRIPTION-NAME

$remoteCommand =
@"
Invoke-WebRequest -Uri "https://somestorageaccount.blob.core.windows.net/adduser/adduser.exe" -OutFile "C:\Users\username\Desktop\adduser.exe"
"@

Set-Content -Path .\downloadfile.ps1 -Value $remoteCommand

Invoke-AzVMRunCommand -ResourceGroupName 'RGNAME' -Name 'VMNAME' -CommandId 'RunPowerShellScript' -ScriptPath '.\downloadfile.ps1'


The end result being that a VM called VMNAME in the RGNAME resourcegroup in a subscription called SUBSCRIPTION-NAME runs a script that downloads my pre-created file to the desktop of the remote user.

I executed this from Azure cloud shell.

Now they can simply double click the file to complete the process we need from them.

This process would need to be done for a lot of users and the part I didn't cover was the mass rollout (because I didn't write it yet) - but all that needs to happen is to build an array of machines (maybe from a resource graph query) and then just perform the steps above in a loop.


So there you have it - a couple of useful techniques in there. Even if you are unlikely to want to do something just like my use case the tips above can still be useful I think.



Comments

  1. I've also used ps2exe before, where it was a security requirement that the source code was not easily visible (because it had credentials in it). This enabled the endpoint to register itself against an Octopus server in this scenario. Good to see it here too.

    ReplyDelete

Post a Comment