<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=1678611822423757&amp;ev=PageView&amp;noscript=1">
Defrag This

| Read. Reflect. Reboot.

Running PowerShell in Vagrant

Dan Franciscus| September 20 2018

| IT insights, PowerShell, Automation, Scripting, How to

running-powershell-in-vagrant

In this article, I will show how to configure a Vagrant box to run PowerShell.

One of key features of Vagrant is the ability to configure virtual machines by using not only traditional configuration management solutions such as Puppet, Ansible and Chef; but also with good old shell scripting. Since Vagrant was built with Linux in mind first, shell script was designed for bash. Fortunately, with the growing amount of Windows support in Hashicorps product suite, cmd and PowerShell are also supported for Windows boxes in Vagrant.

Not Just a Linux “Shell”

Whether you are executing bash, cmd or PowerShell on a Vagrant virtual machine, you will use the “shell” provisioner. When executing, there are two main methods, either by an inline command/script or by specifying the path to a script file relative to your Vagrant root folder.

There are also various options to add in Vagrant when executing shell. Vagrant offers two options that are specific to PowerShell. These are powershell_args and powershell_elevated_interactive. As you could guess, powershell_args means additional arguments to pass to powershell.exe. With the powershell_elevated_interactive option, this means that a PowerShell script will executive with privileges with the logged on user, in addition the “privileged” Vagrant option must also be set to “True”. Note that with the “privileged” field  set to “true”, the script runs as a schedule task on Windows.

PowerShell Demo

In this example, I want to write the script directly in my Vagrantfile, so I use the inline option to install the Chocolatey client on my Vagrant virtual machine during provisioning.

test.vm.provision "shell", inline: <<-SHELL

       Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

       Set-TimeZone 'Eastern Standard Time'

SHELL

The output in Vagrant would appear something like this:

   test: Running: inline PowerShell script

    test: Getting latest version of the Chocolatey package for download.

    test: Getting Chocolatey from https://chocolatey.org/api/v2/package/chocolatey/0.10.11.

    test: Downloading 7-Zip commandline tool prior to extraction.

    test: Extracting C:\Users\ADMINI~1\AppData\Local\Temp\chocolatey\chocInstall\chocolatey.zip to C:\Users\ADMINI~1\AppData\Local\Temp\chocolatey\chocInstall...

    test: Installing chocolatey on this machine

    test: Creating ChocolateyInstall as an environment variable (targeting 'Machine')

    test:   Setting ChocolateyInstall to 'C:\ProgramData\chocolatey'

    test: WARNING: It's very likely you will need to close and reopen your shell

    test:   before you can use choco.

    test: Restricting write permissions to Administrators

    test: We are setting up the Chocolatey package repository.

    test: The packages themselves go to 'C:\ProgramData\chocolatey\lib'

    test:   (i.e. C:\ProgramData\chocolatey\lib\yourPackageName).

    test: A shim file for the command line goes to 'C:\ProgramData\chocolatey\bin'

    test:   and points to an executable in 'C:\ProgramData\chocolatey\lib\yourPackageName'.

    test: Creating Chocolatey folders if they do not already exist.

    test: WARNING: You can safely ignore errors related to missing log files when

    test:   upgrading from a version of Chocolatey less than 0.9.9.

    test:   'Batch file could not be found' is also safe to ignore.

    test:   'The system cannot find the file specified' - also safe.

    test: chocolatey.nupkg file not installed in lib.

    test:  Attempting to locate it from bootstrapper.

    test: PATH environment variable does not have C:\ProgramData\chocolatey\bin in it. Adding...

    test: WARNING: Not setting tab completion: Profile file does not exist at

    test: 'C:\Users\Administrator\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1'.

    test: Chocolatey (choco.exe) is now ready.

To further illustrate running PowerShell in Vagrant, I will incorporate the powershell_elevated_interactive option in my Vagrantfile. Here, I want to stop the netlogon service, which would require administrative privledges.

Vagrant.configure("2") do |config|

    config.vm.define "test" do |test|

        test.vm.box = "eratiner/w2016x64vmX"

        test.vm.network "private_network", ip: "192.168.10.24"

        test.vm.hostname = "test"

        test.vm.provision "shell", privileged: "true", powershell_elevated_interactive: "true", inline: <<-SHELL

        Restart-Service -Name wuauserv –Force -Verbose

        SHELL

    end

  end

After running vagrant up, we see the privileged option ran without error:

==> test: Running provisioner: shell...

    test: Running: inline PowerShell script

    test: VERBOSE: Performing the operation "Restart-Service" on target "Windows Update (wuauserv)".

In the next example, I want to run a PowerShell script that is stored in my Vagrant root folder named Restart-WUService. This script does the same thing the above shell command does: restart the Windows Update Service. Note that Vagrant copies the script from my host machine to the guest virtual machine into the script vagrant-shell.ps1 and runs it remotely.

Here, I show via the ls command on my Mac that my PowerShell script is in my Vagrant root folder:

Dans-MacBook-Pro:vagrant-powershell dan$ ls

Restart-WUService.ps1           VagrantFile

In my Vagrantfile, I have removed my inline shell configurations and instead just point to my local PowerShell script Restart-WUService.ps1.

Vagrant.configure("2") do |config|

    config.vm.define "test" do |test|

        test.vm.box = "eratiner/w2016x64vmX"

        test.vm.network "private_network", ip: "192.168.10.24"

        test.vm.hostname = "test"

        test.vm.provision "shell", privileged: "true", powershell_elevated_interactive: "true", path: "Restart-WUService.ps1"

    end

  end
==> test: Running provisioner: shell...

    test: Running: Restart-WUService.ps1 as c:\tmp\vagrant-shell.ps1

    test: VERBOSE: Performing the operation "Restart-Service" on target "Windows Update (wuauserv)".

Conclusion

Configuration management is the modern way to provision servers, but in certain circumstances, the ability to run shell scripts is still necessary. Vagrant supports the two most popular methods, bash and PowerShell.

Topics: IT insights, PowerShell, Automation, Scripting, How to

Leave a Reply

Your email address will not be published. Required fields are marked *

THIS POST WAS WRITTEN BY Dan Franciscus

Dan Franciscus is a systems engineer and VMware Certified Professional (VCP) specializing in VMware, PowerShell, and other Microsoft-based technologies. You can reach Dan at his blog (http://www.winsysblog.com/) or Twitter at @dan_franciscus.

Free Trials

Getting started has never been easier. Download a trial today.

Download Free Trials

Contact Us

Let us know how we can help you. Focus on what matters. 

Send us a note

Subscribe to our Blog

Let’s stay in touch! Register to receive our blog updates.