Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wsman ennumerate #2 - "the revenge of wsman enumerate" #193

Closed
smanross opened this issue Sep 20, 2024 · 1 comment
Closed

wsman ennumerate #2 - "the revenge of wsman enumerate" #193

smanross opened this issue Sep 20, 2024 · 1 comment

Comments

@smanross
Copy link

smanross commented Sep 20, 2024

Howdy,

again, thanks for the help on the last one... #192

I have this new code I am trying to make work, and its failing...

WSManFaultError: Received a WSManFault message. (Code: 2150858817, Machine: someserver, Reason: WinRM cannot process the request because the request is missing the element titled 'Enumerate'.)

...BUT I have a work-around!!! :)

# client code
wsman = WSMan(
    "somesystem",
    ssl=True,
    auth="ntlm",
    encryption="always",
    username="someuser",
    password=some"password",
    cert_validation=False)

resource_uri = "http://schemas.microsoft.com/wbem/wsman/1/config/listener"
resource = None
option_set = None
selector_set = None
timeout=30

element = wsman.invoke(WSManAction.ENUMERATE, resource_uri, resource, option_set, selector_set, timeout)

How would I go about addind/inserting this into the psrp.wsman code? i.e. is there a place that it makes sense (options, resource) or is it all module changes? (I'm guessing the latter).

It's certainly not a production-worthy change and only a down and dirty example of how I fudged it by inserting the appropriate XML into WSMan.invoke()'s XML.

# workaround code to psrp.wsman.WSMan()
class WSMan(object):

    # on or around line 432
    def invoke(
        self,
        action: str,
        resource_uri: str,
        resource: typing.Optional[ET.Element],
        option_set: typing.Optional["OptionSet"] = None,
        selector_set: typing.Optional["SelectorSet"] = None,
        timeout: typing.Optional[int] = None,
    ) -> ET.Element:
       #not showing all of your code
        try: # on or around line 469
            # start my code - add bits to the envelope (insert an additional xmlns)
            new_envelope_part = 'xmlns:wsmv="http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd" xmlns:wsen="http://schemas.xmlsoap.org/ws/2004/09/enumeration"' 
            xml = xml.decode("utf-8").replace('xmlns:wsmv="http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd"', new_envelope_part).encode("utf-8") 

            # add bits to the body - replace empty body node with the some sane values
            new_body = '<s:Body><wsen:Enumerate><wsman:OptimizeEnumeration/><wsman:MaxElements>2000</wsman:MaxElements> </wsen:Enumerate></s:Body>'
            xml = xml.decode("utf-8").replace("<s:Body />", new_body).encode("utf-8") 
            # end my code
            response = self.transport.send(xml)

        # snip more of your code
        return response_xml

In the end, my enumerate code resulted in the object I was looking for after I altered the XML in this way (based on some google searches for similar scenarios)

...and my query resulted in:
<Element '{http://www.w3.org/2003/05/soap-envelope}Envelope' at 0x000001DBA96CCEF0>
... which I could then iterate through to see the various nodes via:
list(element.iter())

I know you are unreachable for a while, but wanted to give an update since I had one.

Please and thank you for any help. I don't like SOAP (the bathing kind is okay) but understand the programming kind to a degree. :)

Steven

If it matters... this is the link I found the solution from

https://learn.microsoft.com/en-us/answers/questions/1323583/winrm-wsman-enumerate-pullresponse-size

@smanross
Copy link
Author

and now... even better:

my enumerate code without having to mod your code at all...
P.S. I have get(), enumerate(), create() and delete() working on the winrm/config/listener endpoint. YAY!

class WSManClient(object):
    # ignore the rest of this class it as I'm just creating a pypsrp.WSMan() object in __init__() and storing it on self.wsman
    def enumerate(self):
        # the element tree below generates this in the body
        # '<s:Body><wsen:Enumerate><wsman:OptimizeEnumeration/><wsman:MaxElements>2000</wsman:MaxElements> </wsen:Enumerate></s:Body>'

        resource = ET.Element("{%s}%s" % (NAMESPACES["wsen"], "Enumerate"))

        optimize = ET.Element("{%s}%s" % (NAMESPACES["wsman"], "OptimizeEnumeration"))
        max_elements = ET.Element("{%s}%s" % (NAMESPACES["wsman"], "MaxElements"))
        max_elements.text = "2000"
        resource.append(optimize)
        resource.append(max_elements)

        # self.wsman.enumerate is pypsrp.wsman.WSMan().enumerate()
        element = self.wsman.enumerate(resource_uri="http://schemas.microsoft.com/wbem/wsman/1/config/listener", resource=resource)

        myxml = ET.tostring(element, encoding="utf8").decode("utf8")
        obj = xmltodict.parse(myxml)
        myjson = json.loads(json.dumps(obj))
        body = myjson["s:Body"]

        return body

Sorry it took me so long to figure all this out. Thanks again for the module.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant