Running PowerShell in Vagrant

Running PowerShell in Vagrant

Posted on September 20, 2018 0 Comments

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.

 

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.

Comments

Comments are disabled in preview mode.
Topics

Sitefinity Training and Certification Now Available.

Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.

Learn More
Latest Stories
in Your Inbox

Subscribe to get all the news, info and tutorials you need to build better business apps and sites

Loading animation