VirtualBox PowerShell Module

Discussion about using the VirtualBox API, Tutorials, Samples.
SmithersTheOracle
Posts: 60
Joined: 28. Dec 2019, 08:58
Primary OS: MS Windows 7
VBox Version: PUEL
Guest OSses: Windows, Linux

Re: VirtualBox PowerShell Module

Post by SmithersTheOracle »

Well as ready as it ISN'T, I've decided to at least post what I've got for now. If anyone wants to use this, they're free to do so. But understand that it is provided as-is, with no guarantees or warranties. Also, I'm not getting paid for this, so don't demand things if you want them. If you'd like to contribute, send a PM or post. Andrew, I sent you an invite. We'll need to start consolidating the two modules at some point. For now, at least until the rest of the bugs are worked out of mine, I think it'll be better to keep them separate.

https://github.com/SmithersTheOracle/VirtualBoxPS
Andrew Brehm
Posts: 42
Joined: 28. Mar 2012, 17:19

Re: VirtualBox PowerShell Module

Post by Andrew Brehm »

I agree. I have accepted in the invite, and invited you to my repo. I also added a line to the readme to point to your module with a remark that we intent to merge them in the future.

I think PowerShell modules can easily coexist if the cmdlets have different names. I have these names:

Get-VirtualBoxVM
New-VirtualBoxVMObject
Open-VirtualBoxVMConsole
Start-VirtualBoxVM
Stop-VirtualBoxVM
Submit-VirtualBoxVMPowerShellScript
Submit-VirtualBoxVMProcess

Ay obvious collisions?
SmithersTheOracle
Posts: 60
Joined: 28. Dec 2019, 08:58
Primary OS: MS Windows 7
VBox Version: PUEL
Guest OSses: Windows, Linux

Re: VirtualBox PowerShell Module

Post by SmithersTheOracle »

Yeah they should be able to coexist. The only collisions I see would be Get-VirtualBoxVM, Start-VirtualBoxVM, and Stop-VirtualBoxVM. I can rename all my functions back to using an [Action]-VBox[OBJ] naming convention such as Get-VBoxVM for now if you want. We can just hammer out all the names when we merge them. One thing I'd like to do though, looking at your module, is to split some of the functions up. It'll be easier to locate the function you want for each action that way. Get-VirtualBoxVM seems to handle a lot of workload.

I'd also like to put in a ticket eventually with the devs to request that VBoxWebSrv gets service controls, so it can be launched as a service. Also to create the service when VirtualBox is installed. Maybe even a request to add built-in OpenSSL support so it can be started https natively. The former wouldn't be too much work, as it's just responding to start/stop controls and would give dependencies.

Devs: Is there a Managed Object Browser for the web service that I'm missing? It'd really accelerate the creation of this module. It's been a whole lot of guess work finding where to get the session tokens, where they can be used and so forth.
Andrew Brehm
Posts: 42
Joined: 28. Mar 2012, 17:19

Re: VirtualBox PowerShell Module

Post by Andrew Brehm »

Get-VirtualBox handles everything. The other cmdlets just call it. It's similar to how PSWindowsUpdate appears to work. The reason is that VirtualBox objects, names, and uuids have to be sorted out every time and I didn't want to write that code twice. I'll look into it.
SmithersTheOracle
Posts: 60
Joined: 28. Dec 2019, 08:58
Primary OS: MS Windows 7
VBox Version: PUEL
Guest OSses: Windows, Linux

Re: VirtualBox PowerShell Module

Post by SmithersTheOracle »

Ah, that might be where the API will be handy. I've got Get-VirtualBoxVM creating an object and storing all that information in it. Everything is session based, so you can keep re-using the tokens until you close the session. VBoxManage looks like it opens and closes a unique session for each command you pass it.
SmithersTheOracle
Posts: 60
Joined: 28. Dec 2019, 08:58
Primary OS: MS Windows 7
VBox Version: PUEL
Guest OSses: Windows, Linux

Re: VirtualBox PowerShell Module

Post by SmithersTheOracle »

Okay I'm not sure why I didn't think to do it before, but I ran the same command using VBoxManage and got:
VBoxManage.exe: error: The specified user was not able to logon on guest
VBoxManage.exe: error: Details: code VBOX_E_IPRT_ERROR (0x80bb0005), component GuestSessionWrap, interface IGuestSession, callee IUnknown
VBoxManage.exe: error: Context: "WaitForArray(ComSafeArrayAsInParam(aSessionWaitFlags), 30 * 1000, &enmWaitResult)" at line 879 of file VBoxManageGuestCtrl.cpp
I did some searching and quickly found a reference to Chapter 14 Known limitations in your VirtualBox users manual:
Also, to use accounts without or with an empty password, the guest's group policy must be changed. To do so, open the group policy editor on the command line by typing gpedit.msc, open the key Computer Configuration\Windows Settings\Security Settings\Local Policies\Security Options and change the value of Accounts: Limit local account use of blank passwords to console logon only to Disabled.
So my first question is: Why is it I need to switch this GPO if I'm passing it a password?

My second question: Does anyone know of a way to get this error information from the API? Is it the IVirtualBoxErrorInfo attributes? It seems there's something more I could be capturing in this module.
SmithersTheOracle
Posts: 60
Joined: 28. Dec 2019, 08:58
Primary OS: MS Windows 7
VBox Version: PUEL
Guest OSses: Windows, Linux

Re: VirtualBox PowerShell Module

Post by SmithersTheOracle »

Well that's discouraging. I was hoping someone would have seen this. Maybe I need to fill our a bug report instead? Some troubleshooting steps I've taken are: Flipping that GPO between Enabled/Disabled for every troubleshooting step I've taken (doesn't seem to make a difference.) Re-installing guest tools in the guest and rebooting it. Rebooted the host multiple times. Tried multiple variations of the guestcontrol command. The most success I've seen so far is running this:

Code: Select all

PS C:\Program Files\Oracle\VirtualBox> & cmd /c vboxmanage.exe guestcontrol "2016 Core" --domain LOC --username LOCAdmin --password $serv2016creds.GetNetworkCredential().Password start --exe "C:\\Windows\\System32\\cmd.exe" -- "cmd /c echo test >> C:\\Test.txt"
I get no errors and I see it launch a new VBoxService.exe, conhost.exe, and cmd.exe process in the guest. Those processes stay running (I just woke up and checked) and new instances don't close the old instances.

I've tried replacing the "start" with a run command like so:

Code: Select all

PS C:\Program Files\Oracle\VirtualBox> & cmd /c vboxmanage.exe guestcontrol "2016 Core" --domain LOC --username LOCAdmin --password $serv2016creds.GetNetworkCredential().Password run --exe "C:\\Windows\\System32\\cmd.exe" -- "cmd /c echo test >> C:\\Test.txt"
This gives no errors, but it gives me what looks like a command prompt in the guest OS from my host. I can't type anything or do anything with it, but ctrl-c gets me out of it. I say it looks like a command prompt in the guest, because I see all those same processes spawn while I've got the prompt up. When I interrupt, it closes those process instances in the guest.

I ran a debug and checked vbox.log. I see that each VBoxService.exe process is keeping a session open. Everything else looks normal.

I know I'm just missing something simple. Does anyone have any ideas? This one's got me stumped for some reason.
SmithersTheOracle
Posts: 60
Joined: 28. Dec 2019, 08:58
Primary OS: MS Windows 7
VBox Version: PUEL
Guest OSses: Windows, Linux

Re: VirtualBox PowerShell Module

Post by SmithersTheOracle »

Okay, so all the bugs are worked out so far. I got the IGuestSession::processCreate() working thanks to this thread: viewtopic.php?f=34&t=89046&p=426969&hil ... ui#p426969 and I've switched the Suspend-VirtualBoxVM to using IConsole::pause() instead of trying to do IMachine::saveState(). I've also added a Resume-VirtualBoxVM command to resume from the pause. I'm getting the hang of how the web service handles the mutable sessions though, so I may add IMachine::saveState() back in later on a switch to Suspend-VirtualBoxVM. I'm cleaning up some new changes I've made to the VM class across the script, then I'll post a (finally) usable update to Github.

Andrew: Now that I have IGuestSession::processCreate() working, my next set of functions will revolve around running commands inside the guest. You'll be able to use them to run updates and the like. Is there anything in particular you'd need me to focus on first? Will a generic Invoke-VirtualBoxGuestCommand function work for how you're using it? Are there any parameters you'd want to see?

Last thing that's still bugging me is launching a VM in gui mode when it's encrypted. I hand it the disk password(s) and it works, but the GUI still pops up asking for the password... you can even see the VM starting fine right behind it! I've thought of a couple of ways around it, but we'll see. It's not a top priority since you can just click a couple of cancel buttons and it goes away.
SmithersTheOracle
Posts: 60
Joined: 28. Dec 2019, 08:58
Primary OS: MS Windows 7
VBox Version: PUEL
Guest OSses: Windows, Linux

Re: VirtualBox PowerShell Module

Post by SmithersTheOracle »

At this point I've tried injecting the disk password at every machine/lock state I could find with no luck. The earliest I can do it is after the machine state is "Paused" and the machine process's lock on itself created by IMachine::launchVMProcess() releases its write lock. It looks like there won't be any way around using the GUI front-end and it asking for the password. I don't like to move on without fixing old bugs, but this one is getting an exception unless anyone has any other thoughts. In case someone wants to say, "Well just write a front-end" remember that this might be happening from a remote computer without access to the host computer's COM. I'm looking to write a solution that leverages what's available to the web service natively. It's a shame VirtualBox doesn't have TPM 2.0 support, but I understand the complexity in that.
SmithersTheOracle
Posts: 60
Joined: 28. Dec 2019, 08:58
Primary OS: MS Windows 7
VBox Version: PUEL
Guest OSses: Windows, Linux

Re: VirtualBox PowerShell Module

Post by SmithersTheOracle »

Quick update:

Added New-VirtualBoxVM function
New-VirtualBoxVM currently only has basic functionality but will create the shell of a VM
Added ISystemPropertiesSupported class for future parameter validation in New-VirtualBoxVM
Modified Start-VirtualBoxSession to populate [ISystemPropertiesSupported]$global:systempropertiessupported on first run
Added -Force switch to Start-VirtualBoxSession to force update to $global:systempropertiessupported
Updated help text for Start-VirtualBoxSession to include -Force switch

Still working on:
Convert New-VirtualBoxVM 'Custom' parameter set parameters to dynamic parameters
Update help text for New-VirtualBoxVM
SmithersTheOracle
Posts: 60
Joined: 28. Dec 2019, 08:58
Primary OS: MS Windows 7
VBox Version: PUEL
Guest OSses: Windows, Linux

Re: VirtualBox PowerShell Module

Post by SmithersTheOracle »

Has anyone tested any of the functions? Any feedback or bugs for me? I haven't had time to go through and thoroughly test everything so there has to be something I've missed.
Andrew Brehm
Posts: 42
Joined: 28. Mar 2012, 17:19

Re: VirtualBox PowerShell Module

Post by Andrew Brehm »

SmithersTheOracle wrote:Has anyone tested any of the functions? Any feedback or bugs for me? I haven't had time to go through and thoroughly test everything so there has to be something I've missed.
I'll get to it tomorrow.
Andrew Brehm
Posts: 42
Joined: 28. Mar 2012, 17:19

Re: VirtualBox PowerShell Module

Post by Andrew Brehm »

I updated my PowerShell module

Get-VirtualBoxVM
New-VirtualBoxVMObject
Invoke-VirtualBoxVMPowerShellScript
Invoke-VirtualBoxVMProcess
Open-VirtualBoxVMConsole
Start-VirtualBoxVM
Stop-VirtualBoxVM
Submit-VirtualBoxVMPowerShellScript
Submit-VirtualBoxVMProcess

Submit-* is equivalent to Invoke-* -AsJob

This allows for throwing a PowerShell command at an array of VMs and follow their progress as PowerShell jobs.
Post Reply