Fix 31344

funcitons now use OutputTo-Json
Fixes problem with returning values with spaces
list_installed only needs to call Get-WindowsFeature once
This commit is contained in:
twangboy 2016-03-30 16:00:00 -06:00
parent 0f5e67de5d
commit 1d5bcee390

View file

@ -4,6 +4,7 @@ Manage Windows features via the ServerManager powershell module
'''
from __future__ import absolute_import
import logging
import json
# Import python libs
try:
@ -24,13 +25,13 @@ def __virtual__():
Load only on windows with servermanager module
'''
if not salt.utils.is_windows():
return (False, 'Failed to load win_servermanager module:\n'
'Only available on Windows systems.')
return False, 'Failed to load win_servermanager module:\n' \
'Only available on Windows systems.'
if not _check_server_manager():
return (False, 'Failed to load win_servermanager module:\n'
'ServerManager module not available.\n'
'May need to install Remote Server Administration Tools.')
return False, 'Failed to load win_servermanager module:\n' \
'ServerManager module not available.\n' \
'May need to install Remote Server Administration Tools.'
return __virtualname__
@ -46,34 +47,23 @@ def _check_server_manager():
python_shell=True)
def _pshell(func):
def _pshell_json(cmd, cwd=None):
'''
Execute a powershell command and return the STDOUT
Execute the desired powershell command and ensure that it returns data
in json format and load that into python
'''
return __salt__['cmd.run']('{0}'.format(func),
shell='powershell',
python_shell=True)
def _parse_powershell_list(lst):
'''
Parse command output when piped to format-list
Need to look at splitting with ':' so you can get the full value
Need to check for error codes and return false if it's trying to parse
'''
ret = {}
for line in lst.splitlines():
if line:
splt = line.split()
# Ensure it's not a malformed line, e.g.:
# FeatureResult : {foo, bar,
# baz}
if len(splt) > 2:
ret[splt[0]] = splt[2]
ret['message'] = lst
if 'convertto-json' not in cmd.lower():
cmd = ' '.join([cmd, '| ConvertTo-Json'])
log.debug('PowerShell: {0}'.format(cmd))
ret = __salt__['cmd.shell'](cmd, shell='powershell', cwd=cwd)
try:
ret = json.loads(ret, strict=False)
except ValueError:
log.debug('Json not returned')
return ret
def list_available():
'''
List available features to install
@ -87,8 +77,9 @@ def list_available():
salt '*' win_servermanager.list_available
'''
return _pshell('Get-WindowsFeature -erroraction silentlycontinue '
'-warningaction silentlycontinue')
cmd = 'Get-WindowsFeature -erroraction silentlycontinue ' \
'-warningaction silentlycontinue'
return __salt__['cmd.shell'](cmd, shell='powershell')
def list_installed():
@ -105,22 +96,16 @@ def list_installed():
salt '*' win_servermanager.list_installed
'''
cmd = 'Get-WindowsFeature -erroraction silentlycontinue ' \
'-warningaction silentlycontinue | ' \
'Select DisplayName,Name,Installed'
features = _pshell_json(cmd)
ret = {}
names = _pshell('Get-WindowsFeature -erroraction silentlycontinue '
'-warningaction silentlycontinue | Select DisplayName,Name')
for line in names.splitlines()[2:]:
splt = line.split()
name = splt.pop(-1)
display_name = ' '.join(splt)
ret[name] = display_name
state = _pshell('Get-WindowsFeature -erroraction silentlycontinue '
'-warningaction silentlycontinue | Select Installed,Name')
for line in state.splitlines()[2:]:
splt = line.split()
if splt[0] == 'False' and splt[1] in ret:
del ret[splt[1]]
if '----' in splt[0]:
del ret[splt[1]]
for entry in features:
if entry['Installed']:
ret[entry['Name']] = entry['DisplayName']
return ret
@ -153,11 +138,18 @@ def install(feature, recurse=False):
sub = ''
if recurse:
sub = '-IncludeAllSubFeature'
out = _pshell('Add-WindowsFeature -Name {0} {1} '
'-erroraction silentlycontinue '
'-warningaction silentlycontinue '
'| format-list'.format(_cmd_quote(feature), sub))
return _parse_powershell_list(out)
cmd = 'Add-WindowsFeature -Name {0} {1} ' \
'-ErrorAction SilentlyContinue ' \
'-WarningAction SilentlyContinue'.format(_cmd_quote(feature), sub)
out = _pshell_json(cmd)
ret = {'ExitCode': out['ExitCode'],
'DisplayName': out['FeatureResult'][0]['DisplayName'],
'RestartNeeded': out['FeatureResult'][0]['RestartNeeded'],
'Success': out['Success']}
return ret
def remove(feature):
@ -182,8 +174,14 @@ def remove(feature):
salt -t 600 '*' win_servermanager.remove Telnet-Client
'''
out = _pshell('Remove-WindowsFeature -Name {0} '
'-erroraction silentlycontinue '
'-warningaction silentlycontinue '
'| format-list'.format(_cmd_quote(feature)))
return _parse_powershell_list(out)
cmd = 'Remove-WindowsFeature -Name {0} ' \
'-ErrorAction SilentlyContinue ' \
'-WarningAction SilentlyContinue'.format(_cmd_quote(feature))
out = _pshell_json(cmd)
ret = {'ExitCode': out['ExitCode'],
'DisplayName': out['FeatureResult'][0]['DisplayName'],
'RestartNeeded': out['FeatureResult'][0]['RestartNeeded'],
'Success': out['Success']}
return ret