Search code examples
pythonpowershellpexpect

Pexpect PopenSpawn based interface to PowerShell causing issues


so I've used pexpect popenSpawn rather extensively with just a cmd interface with success. With powerShell, I'm having trouble. if i step through it using pdb, it works, however, it fails when i run it...something timing related, bizarre: searchString fails to find a match.

here's my code:

#attempts to enable the openSSH feature within windows
#follows the steps laid out here:https://learn.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_firstuse
import pexpect, re
from pexpect.popen_spawn import PopenSpawn

def installOpenSSH(restart = False):
    
    c = pexpect.popen_spawn.PopenSpawn('PowerShell', encoding='utf-8')
    
    c.sendline('Start-Process PowerShell -Verb RunAs')
    try:
        c.expect('PS.*>', 10)
    except Exception as e:
        print(f'Exception {e} thrown attempting to spawn powershell w/ admin priviledges')
        return False
    
    c.sendline("Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'")
    try: 
        c.expect('PS.*>', 10)
    except Exception as e:
        print(f'Exception {e} thrown attempting to get windows capability for ssh')
        return False

      
    retString = c.before
    print(f'received {c.before}')
    searchString = "^Name(.*)(OpenSSH.Server.*)\n*(State.*):(.*)"   #capture the opehSSH server matching string (state : Installed)
    sresults = re.search(searchString,retString,re.MULTILINE)
    if 'Installed' in sresults[sresults.lastindex]:
        print('ssh server already installed')

Solution

  • def installOpenSSH(restart = False):
        c = pexpect.popen_spawn.PopenSpawn('PowerShell', encoding='utf-8')
        time.sleep(2)
        c.sendline('Start-Process PowerShell -Verb RunAs')
        time.sleep(2)
        try:
            c.expect('PS.*>', 10)
        except Exception as e:
            print(f'Exception {e} thrown attempting to spawn powershell w/ admin priviledges')
            return False
        time.sleep(2)
        c.sendline("Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'")
        try: 
            c.expect('PS.*>', 10)
        except Exception as e:
            print(f'Exception {e} thrown attempting to get windows capability for ssh')
            return False
    
        featureRequiresRestart = False
            
        retString = c.before
        searchString = "^Name(.*)(OpenSSH.Server.*)\n*(State.*):(.*)"   #capture the opehSSH server matching string (state : Installed)
        sresults = re.search(searchString,retString,re.MULTILINE)
        if 'Installed' in sresults[sresults.lastindex]:
            print('ssh server already installed')