How to run scripts in your Azure VM by using Run Command 🔧

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
>> My name is Thomas Mauer. I'm a Cloud Advocate at Microsoft. In today's video we're going to have a look how you can run scripts like PowerShell scripts or shell scripts against Azure VMs without having network connectivity to those VMs. We're going to even have a look at how you can run these scripts against multiple Azure VMs at the same time, so stay tuned. [MUSIC] One thing we often see is that, for example, you don't have network access to a VM. This can be multiple reasons like you cannot have it from a company perspective where the network setup just doesn't allow you to, or you need to, for example, troubleshoot one of these VMs like you, for example, changed an IP address inside that VM or you just disabled the network adapter or you did some other configuration things like disabled RDP or SSH. You want to make sure that you have a way of actually running and troubleshooting these VMs, as well as building automation for your virtual machines. We're going to have a look at the Run command, which is part of the Azure Compute PowerShell modules, as well as the CLI, as well as REST APIs. The same thing also available in the portal. Let's have a quick look here at the portal itself. You can see here, I'm running a couple of virtual machines. There are some windows Virtual Machines and Linux virtual machines. If I click, for example, on one of these, you will see that. Again, this virtual machine here is running and you can see some information here what I'm actually doing. Now what you can also see here is that this machine here only has a private IP address. There's no way for me to go over the Internet and actually connect to that machine. I have a couple of options here now. If I want to work with that machine, I could have a VPN tunnel, I could have Azure express route, I could have a chump post which I can go through or I could use tools like Azure Bastion to access that. However, if I don't have that or something is broken with that VM, I can use some other tricks here. First before I go on, I actually want to show you that I don't have access to that machine from my computer. Let's just try to ping this machine here. You will see, obviously since I don't have a VPN setup or anything, I'm not based in the same virtual network, so I can't reach that machine, I cannot go and access that VM. But I still want to run some scripts against it or I want to run some commands against it. Let's have a look, what we have here. The portal already offers you a couple of options and if you scroll all the way down here to operations, again, we have tools like guest and host updates, backup, Azure Bastion, which allows you to do a remote desktop connection over the web or an SSH connection. But again, if for example, you want to run a script, that's maybe not really the way to go. Also, if you, for example, shut down your RDP port on the machine itself or the SSH port, you probably don't have access to it. For that, we have a tool called Run command. If I go to Run command, you will see here by default we already offer you a couple of different scripts which you can use to troubleshoot. For example, you can go in here and say, I want to set different RDP port. I want to reset the RTP certificates or the general the RTP settings. I can just simply run a IPConfig to figure out what IP addresses are configured on that machine. I can enable Windows Update PowerShell remoting, reset the admin accounts and much, much more. All the things I might need to actually go in and troubleshoot that machine. However, if I need to run something different, I could go and just run a PowerShell script. In this case, I could click on this "Run PowerShell Script". I can enter my PowerShell script, which is here, just a simple get service. Now I can hit "Run" and you can see here that this will now run that script on that specific VM. Now, the question here is now, why would I do that? Obviously again, because I don't have access to it. How does that script actually goes and access that machine? Well, we have something called the VM guest agent, which is deployed in every Azure VM, which then goes in and actually does the communication. We use that for example for backups scenarios, we use that for monitoring and we can also leverage that for the Run command. Now we get the results back and you can see here, I get all the services running in that specific Azure Virtual Machine. Again, we have the same thing also for Linux machines where you actually just can run shell scripts and some additional troubleshooting commands as well. However, I want to show you something else cool. Now if I want to build a little bit more than that and obviously I don't want to maybe use the portal all the time, I want to run a script, I want to build some automation. What I can do here is I could go, for example, to my local PowerShell Windows terminal and run their commands. But I can also go here, for example, into Azure Cloud Shell, which allows me to basically already has installed the Azure CLI, it has Azure PowerShell, and a couple of other things here. Now, let's say I want to run a script against that machine. First of all, what we do is we create a script here. Let's do code script.ps1. Now we can write our script. Again to make it simple, I will again, just stay here with Get-Service so I can close the editor here. Now, I've script here, which I want to run against that VM. To run that we have a simple command called invoke.AzVMRunCommand. What we need to do is we need to define a resource group name. This VM we just saw is basically in that Test Azure VMs resource group, we also obviously need to add the name of the virtual machine. This one is the azvm001. Then we need to do some additional things. We need to define what actually command we want to run. We have commandId, which is run PowerShell script. Then we want to give this ScriptPath, and this is just a file I just created. This is like a locally stored script. So this script could be like if you run that in Azure PowerShell on your local machine, this will need to be locally stored, in this case, it's stored into my Azure Cloud Shell. If I now run that command, it will basically do the same thing as I just did in the portal, but you can see that I can now leverage this to build a little bit of automation around it. Now, you can see we get some output here. It finished running. It gave me back some output. You can see here that it's a little bit sorted, that it's not just an object we get back, we actually get some text message back. If you run, we get some value as well as then actually the result of like Get-Service back as a message here. For example, in this sense we need to know, so if you want to use that programmatically, we didn't also need to obviously work with that and I will show you just how that works. But you get the sense that I now could actually go out, and run this command just a couple of times against different machines to achieve something. I cannot just do a Get command. I could configure actually something within that machine. Now, if you want to learn more about this, there is obviously documentation on Microsoft Docs where we actually have documentation how you can leverage that Commandlet. Again, this is not just limited to PowerShell. We also have a Azure CLI command as well as a REST API which you can leverage for that. Now, what I want to show you though is, I want to show you how you could, for example, leverage this, and build some automation around it so you can run it against multiple Azure VMs. So for that, let me go into my local VS Code here. What I'm going to do here is, I'm first going to paste the command I just used. I'm going to use the Invoke command I just run against my machine. What you can see here, I already have a script, PS1, and this is the script I'm going to fire against a couple of different Azure VMs in just a bit. What this command does basically, it goes out and reads a registry key, like the Virtual Machine is running on a host in Azure, and I can actually get the name of that host of that Azure host by checking out the registry. So that is what I'm doing here. Again, I put you that link into the description. If you want to find out more about that command, you can actually check that blog post out. Let me quickly work on this here. What I'm going to do here is, before I start working, let me quickly clean this up a little bit. So I have Run command. Then I want to split this basically on a little bit of multiple lines here, so I get some better views here. Do that. Let me quickly do this. Now, I just basically go here, and format that ScriptPath. It's probably good to have it like this. Next thing is, again, I can now run this against my machine. The first thing I want do is obviously, I want to actually go out and set a variable subscription ID. So what I can do here is, I can then just enter my subscription where I want to run it against. I'm not going to do that right now. But again, you could actually select that for the variable. The next thing I want do is, I want to run that command now against a couple of different VMs. All the VMs in my case, which I want to run it against, are stored in the same resource group. What I want to define, I want to have a variable called Resource Group. Then we're going to use that test-azurevms-rg. Now what we can leverage is, we can leverage that variable here, and just put this in here instead of having to run that manually there. Now, what I also want to do is, obviously I need before I fire that, I want to set the context. I want to select the right subscription. So what I would do, set subscription, and then I will just go and say Subscription ID. With that, I would make sure that I run this command against the VMs in the right subscription. I just want to make sure that I do that. Now, the next thing I will do is, I would actually go out and get all the Azure VMs I want to run it against. Again, now I'm doing this based on actually a resource group, however you could run just like a simple counter or whatever, or you could import a CSV file or anything basically to get the list of Azure VMs. So what I'm going to do here is, I'm just going to do my Azure VMs, and what I want to do is, I want to Get-AcVm. Then I need to define the ResourceGroupName where the VMs are in. Again, I already have a variable here, so I can get that. Let me quickly run this here first, so set this, and then I can, for example, just run and list all the VMs within that resource group. I'm going to run this here, and in the Terminal here, you will see here all the VMs listed. We have all the VMs, the six VMs you saw earlier in the Azure portal. However, I want to filter that, because it could be that one of these VMs are, for example, down. So what I want to add is, I want to see the status. So I have a Status switch here, so I want to get the status of these VMs. You can see here the difference now if I run this, what you will see here is, that I also see if the VM is actually running. Currently they're all in running state. But however, it could be that the VM is not running, in that case, I don't want to send that AcVm run command against that VM because it would just throw an error. What I'm going to do here is, I'm going to select Where-Object. Then basically say, Okay. I want to see if the PowerState is equal VM running. So what I can do here, this should give me the exact same output. Let's have a look at this, and if everything worked, I still get my six VMs, because everything we have done is running, so that is great. The next thing I want to do, I also want to make sure that this script now, obviously is running against Windows VMs. In this sense, I'm just going to hit "Add," and then I'm going to do StorageProfile, I'm going to select OsDisk, and then I'm going to go to OsType, and that should be equal Windows. If I run this here, and quickly select this, I can just basically go out, and again, I should see all of them, because again, all of these are Windows VMs. If there will be a Linux VM now in that specific resource group, basically, don't run that against it. Now, I have my VMs here. The next thing I want do is actually, I want to run that now, this command here against all of the VMs. So what I'm going to do here is, I'm going to use that variable or this VM object, and I'm going to do a ForEach-Object, and then here I actually want to run that command. So let's put this in here. I can now run that command. It would now go around all these different VMs, it would then run that same script against it. Let me quickly run this to show you what that actually would do to these virtual machines. I'm still running that command. At the moment, I'm not doing any of the ForEach. You can see here, I only selected that specific command. I'm running that against one of the VMs, but you will see the output in just a bit. You can see here that I now got some information back here. Again, I use some video editing to actually make this a little bit faster. When you run this script, we will see it will take awhile actually until you get the value back because it needs some time to actually connect to Azure and then provide that to the VM, and from there, you get the message back. That will take awhile. But what do you can see here on the message, you can see here I get the information back. It says "HostName", and then I get the host name of the Hyper-V host or the Azure host basically, where this machine is running on, which is pretty cool. But again, you could run any other command to get some information out of that yam, or even configure something within that machine. What I want to do now here is obviously, I want to define that this is now running in actually in that ForEach. So what I'm going to say here, I don't want to run it all the time against the same machine, so what I'm going to do here is just going to use my name here. So this will then use the name of the VM, which is in that loop. Now, what I also want to do here is actually, I want to go and format the output a little bit. I want to save this here in a variable because I don't necessarily want all that information here, which I have around this. For example, I don't want to know that this succeeded, and so on; I just care about this message. So what I'm going to do here, I'm going to configure out, and then I create an output. This is what I actually want. Let's say "Output", and then let's say, I also want to run this against multiple machines, so I want to make sure that I know from which machine that output comes from, so I'm going to use ".Name" again. This will then just output the name of this VM, and then I'm going to do a space, and then I actually want to have the output of the message I get back. I'm going to do that, and I'm using "Value", and then this is the 0, and then I'm going to do "Message". That will then just basically put that out, and I want to then basically get this back, so I'm going to output that. That is now what I actually would run. I would actually go out and run this now against multiple machines. What will happen is, it will then go and start with the first machine, and as the first machine is done, it will run that against the second machine, against the third machine, and so on. As you can imagine, this will take some time to complete. What I can do now with PowerShell 7 actually is I can run this ForEach-Object in parallel. This now allows me actually to run that command in parallel. I want to make a nice code here. I can run that, and it will actually go out and run it for the first machine, and the second machine, and the third machine, all at the same time. The first thing I want to do is obviously, run the resource group. Again, you can go out, and if you have multiple subscription in your Azure account, in your Azure tenant, you probably want to set here the Azure subscription ID, and then obviously, set that as the context you're running your commands on. I highly recommend doing that. I already did it in my environment. The next thing I want to do here is, I'm going to run this command to actually get all the Azure VMs, which are in that resource group, which are running, and which are Windows, in that case. I'm going to run this, and we also do a quick check here. So if I do "MyAzureVMs", I have a list of these VMs. I want to run now a ForEach here. One thing I need to change though is, obviously, because I want to use the resource group, so what I'm going to use here, instead of this, I'm going to enter the resource group name. I'm going to use whatever is given from that VM object. Now, I can actually run this command. This will take awhile again until everything has started, but it will then provide me with all the information from all the different server, so I will see all the host names of the Azure VMs, or where they running on. Now, you can see here, I get the results back almost at the same time. Some hosts are a little bit faster in responding than others. You can see here, I get for the azvm001, 002, 004, 003, and 005, and I think it's really working at 006 to get these results back. However, this is obviously using a feature which came with PowerShell version 7, and you can use it with PowerShell version 7 and higher. With the parallel parameter for ForEach-Object, you can actually go out and run it against all the VMs you have then. Now, I highly recommend there's also a throttle limit you can set. If you have 1,000 VMs or whatever, you probably don't want to run it against all 1,000 at the same time because you could also hit some limitations there, so I recommend that you set the throttle limit there to, let's say, for example, 20 VMs, or 10 VMs, or whatever is suitable for you and your scenario. Then you get all these information back. You can see here, I get all the information from these back, and I get them nicely formatted. I can easily now see what I get back actually, from which host, or from which VM, in that sense. I hope this video was helpful. If you like that video and you want to see more, like that video, subscribe, and if you have any questions, feel free to leave a comment. I will put more links and more information in the description below, and hopefully, see you in the next one. [MUSIC]
Info
Channel: Thomas Maurer
Views: 52,539
Rating: undefined out of 5
Keywords: Microsoft, Azure, Cloud Computing, VM, Virtual Machine, Script, Command, PowerShell, Azure PowerShell, Azure CLI, Bash, Shell, VS Code, Multiple VMs, VMs, Virtual Machines, Azure VMs, Azure VM, AzVMRunCommand
Id: BrL84_5kPx4
Channel Id: undefined
Length: 24min 21sec (1461 seconds)
Published: Sun Mar 07 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.