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.
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.
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)".
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 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.
Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.
Learn MoreSubscribe to get all the news, info and tutorials you need to build better business apps and sites