0

Sorry in advance for silly question.

I am trying to write simple python script that runs virtual machine using PowerShell commands.

I have got a little problem with converting output from PowerShell command to a variable in Python.

The idea is:

I launch virtual machine, after that I check the state of it and, if the state is Running - start all the activity.

It is not a problem to do it in PowerShell, I wrote all the commands (launch VM, check state, if statement etc), but it is a problem to do it from py file.

My script looks like that:

import subprocess
import time
import os


class Utils(object):
    def __init__(self):
        self.ps_exec = r"C:\path\PsExec.exe"
        self.power_shell = r"C:\path\powershell.exe"

    def vm(self, apply_vm_script):
        subprocess.Popen([self.power_shell, apply_vm_script])

util = Utils()

def turn_on_vm(vm_name, checkpoint_name):
    apply_vm_script = 'Invoke-Command -Computername name -ScriptBlock ' \
                           '{ Get-VM ''"' + vm_name + '"'' | get-vmsnapshot -Name ' + '"' + checkpoint_name + '" | ' \
                           'Restore-VMSnapshot -Confirm:$false ; Start-VM -Name ''"' + vm_name + '"''}'
    util.vm(apply_vm_script)
    time.sleep(10)
    
def check_if_vm_on(vm_name):
    check_vm_script = 'Invoke-Command -Computername name -ScriptBlock { Get-VM | where {$_.Name -eq ' + vm_name + ' } | where { $_.State -eq "Running" } | select Name,State}'
    util.vm(check_vm_script)
    time.sleep(3)
    
def test():    
    turn_on_vm('VM_name', 'checkpoint_name')
    if(check_if_vm_on('VM_name')):
        Do my activity
    
def main():
    test()
    
if __name__ == '__main__':
    main()

Also, I can perform all if actions in PowerShell, but also can't convert bool output into Python:

if($State -like '*Running*') { Write-Output "True" }

State was defined earlier, no problem with variables.

Any ideas how to solve it?

Thank you in advance!!!

3
  • Why... are you writing a Python script that runs PowerShell commands? Wouldn't it make sense to write a PowerShell script instead? Commented Jan 5, 2021 at 10:05
  • The main part of the script is Python commands. Only this in PowerShell. Its ok, just a bit easier for me. Commented Jan 5, 2021 at 10:07
  • You might be better off with writing a .ps1 script file that does all those things and takes a couple of arguments (vm name, checkpoint name), so you can a) test or use it independently of your Python script and b) have an easier time running it from Python. Commented Jan 5, 2021 at 10:28

1 Answer 1

5

You need to get the stdout from the powershell script to your python program. This can be done with Popen.communicate().

def vm(self, apply_vm_script):
        p = subprocess.Popen([self.power_shell, apply_vm_script], stdout=subprocess.PIPE)
        result = p.communicate()[0]
        return str(result)

Also you need to return this value from check_if_vm_on

def check_if_vm_on(vm_name):
    check_vm_script = 'Invoke-Command -Computername name -ScriptBlock { Get-VM | where {$_.Name -eq ' + vm_name + ' } | where { $_.State -eq "Running" } | select Name,State}'
    result = util.vm(check_vm_script)
    time.sleep(3)
    return result

Then you will be able to check it with the if statement:

if(check_if_vm_on('VM_name') == "True"):
    Do my activity
Sign up to request clarification or add additional context in comments.

2 Comments

Actually, I think I got it. p = subprocess etc..? Looks like it works, thank you very much. Sorry, but can't vote.
Yes, sorry, p = subprocess. Fixed the answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.