Posts: 11
Threads: 2
Joined: Feb 2017
So a new one for me. Any help appreciated.
I would no doubt be able to find the answer eventually, but its nice to talk to other humans from time to time.
I am trying to query AD at a point in my code, to check to see if a host exists on the domain, i.e. has a computer name entry in there. However, it seems to be doing this backwards, ie 1 for false, and 0 for true. Therefor I assume this is actually an exit code generated by Microsoft command shell and not by Python. Happy to be clarified/corrected on that one.
If I run...
dsquery_test = os.system("dsquery computer -name <hostname>") ...this indeed returns a 1 back to the variable, and believe this is correct boolean for True. Which would be correct.
however if I enter a "fake" hostname that doesn't exit, it also returns a 1.
Running the command from the command line for a real one returns...
"CN=a_hostname,OU=Computers,DC=domain,DC=co,DC=uk"
...running it form the command line for a "fake" one returns an empty string (ie looks like just spaces)
So, what I would like to happen is if it returns an empty string, I can get it to return 0
I would like to be able to print the details out to screen when it does get something. How would I do that also?
(Apologies if this is a bit babble-y, am a bit tired)
Posts: 331
Threads: 2
Joined: Feb 2017
os.system usually returns exit status of command run - and it seams that regardless of existence of hostname dsquery ends with succes exit code (after all, it did its work ...). You need to capture output of command and test it, it can be done with:
import subprocess
result = subprocess.check_output("dsquery computer -name <hostname>") # it can raise an exception ... After that you need to process/parse result.
Posts: 11
Threads: 2
Joined: Feb 2017
Yeah I thought about using the subprocess module but I got the following errors :
Output: >>> import subprocess
>>> result = subprocess.check_output("dsquery computer -name PC0EGP57")
Traceback (most recent call last):
File "<pyshell#13>", line 1, in <module>
result = subprocess.check_output("dsquery computer -name PC0EGP57")
File "C:\Python27\lib\subprocess.py", line 212, in check_output
process = Popen(stdout=PIPE, *popenargs, **kwargs)
File "C:\Python27\lib\subprocess.py", line 390, in __init__
errread, errwrite)
File "C:\Python27\lib\subprocess.py", line 640, in _execute_child
startupinfo)
WindowsError: [Error 2] The system cannot find the file specified
I also tried... (as per : https://docs.python.org/2/library/subprocess.html , although I have not had time to read the whole thing yet.)
Output: >>> import subprocess
>>> result = subprocess.check_output(["dsquery", "computer", "-name", "PC0EGP57"])
Traceback (most recent call last):
File "<pyshell#14>", line 1, in <module>
result = subprocess.check_output(["dsquery", "computer", "-name", "PC0EGP57"])
File "C:\Python27\lib\subprocess.py", line 212, in check_output
process = Popen(stdout=PIPE, *popenargs, **kwargs)
File "C:\Python27\lib\subprocess.py", line 390, in __init__
errread, errwrite)
File "C:\Python27\lib\subprocess.py", line 640, in _execute_child
startupinfo)
WindowsError: [Error 2] The system cannot find the file specifie
...but I figured this second method introduced a little more complexity (only slightly) and went back to the first option.
Posts: 331
Threads: 2
Joined: Feb 2017
Oops, my bad, I forgot that its necessary to split command and arguments or use shell=True (or maybe use some other trick).
Your second option "should" work, perhaps subprocess on windows doesnt use %PATH variable, so cant find dsquery? You can try either
subprocess.check_output("dsquery computer -name xxxx", shell=True) or perhaps try to use complete path
subprocess.check_output(["c:/programfiles/something/dsquery", "computer", "-name", "xxxx"]) If it doesnt help, I am lost (cant test it, I dont have/use windows),
Posts: 11
Threads: 2
Joined: Feb 2017
Thanks for your help with this. it is very much appreciated!
I tend to use Linux also, however my employer has a complete Windows infrastructure, hense the messing around with os and subprocess, to get python to work.
This is odd as if I do something simple...
Output: >>> import subprocess
>>> result = subprocess.check_output("hostname")
>>> result
'PC0EGP57\r\n'
...works perfect, no problem.
But as soon as I start adding other strings...
Output: >>> subprocess.check_output("dsquery computer -name PC0EGP57", shell=True)
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
subprocess.check_output("dsquery computer -name PC0EGP57", shell=True)
File "C:\Python27\lib\subprocess.py", line 219, in check_output
raise CalledProcessError(retcode, cmd, output=output)
CalledProcessError: Command 'dsquery computer -name PC0EGP57' returned non-zero exit status 1
>>> subprocess.check_output(["C:\Windows\System32\dsquery.exe", "computer", "-name", "PC0EGP57"])
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
subprocess.check_output(["C:\Windows\System32\dsquery.exe", "computer", "-name", "PC0EGP57"])
File "C:\Python27\lib\subprocess.py", line 212, in check_output
process = Popen(stdout=PIPE, *popenargs, **kwargs)
File "C:\Python27\lib\subprocess.py", line 390, in __init__
errread, errwrite)
File "C:\Python27\lib\subprocess.py", line 640, in _execute_child
startupinfo)
WindowsError: [Error 2] The system cannot find the file specified
>>> subprocess.check_output("c:\windows\system32\dsquery.exe computer -name PC0EGP57", shell=True)
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
subprocess.check_output("c:\windows\system32\dsquery.exe computer -name PC0EGP57", shell=True)
File "C:\Python27\lib\subprocess.py", line 219, in check_output
raise CalledProcessError(retcode, cmd, output=output)
CalledProcessError: Command 'c:\windows\system32\dsquery.exe computer -name PC0EGP57' returned non-zero exit status 1
Pushing on
Posts: 11
Threads: 2
Joined: Feb 2017
ok update,
I made a mistake, I forgot to change "import os" to "import subprocess"
So...
network_response = subprocess.check_output("ping localhost", shell=True) this works.
However,
If I use it to ping a host that doesn't exist,
>>> network_response = subprocess.check_output("ping idontexist", shell=True)
Traceback (most recent call last):
File "<pyshell#37>", line 1, in <module>
network_response = subprocess.check_output("ping idontexist", shell=True)
File "C:\Python27\lib\subprocess.py", line 219, in check_output
raise CalledProcessError(retcode, cmd, output=output)
CalledProcessError: Command 'ping idontexist' returned non-zero exit status 1 ...It throws an exception as you said.
Nearly there!
Posts: 331
Threads: 2
Joined: Feb 2017
(Mar-02-2017, 02:36 PM)S0undwav3 Wrote: Output: >>> subprocess.check_output("dsquery computer -name PC0EGP57", shell=True)
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
subprocess.check_output("dsquery computer -name PC0EGP57", shell=True)
File "C:\Python27\lib\subprocess.py", line 219, in check_output
raise CalledProcessError(retcode, cmd, output=output)
CalledProcessError: Command 'dsquery computer -name PC0EGP57' returned non-zero exit status 1
....
This works as expected - the command was executed and finished with an error (non-zero exit), so check_output raised CalledProcessError to announce that something went wrong. Same for your third try.
You can use try/except to take care about it:
from subprocess import CalledProcessError
try:
result = subprocess.check_output("dquery computer -name PC0EGP57", shell=True)
except CalledProcessError as e:
print(e) # do something about error ...
Posts: 11
Threads: 2
Joined: Feb 2017
Are you using Py v3.* by any chance?
I am using 2.7
not sure if that make a difference?
Posts: 331
Threads: 2
Joined: Feb 2017
It shouldnt matter here (tried it in 2.7 and 3.5).
Errors in your check_output was due to error exit code of called program. So if
dquery computer -name PC0EGP57
in a terminal returns nothing (PC0EGP57 does not exist?) and ends with an error exit code, then its correct that
subprocess.check_output("dsquery computer -name PC0EGP57", shell=True) stops with CalledProcessError.
If
dsquery computer -name existing_hostname
executed in a terminal returns some information about hostname, then subprocess.check_output should return the exactly same info (as it did with hostname).
If dsquery ... gives some output in a terminal and the same command raises CalledProcessError when run from subprocess.check_output, then its weird program that reports an error exit code even on a success and you need to capture error output too. For that you can try
outputs = subprocess.Popen("dsquery -....", shell=True, stdout=subprocesss.PIPE, stderr=subprocess.PIPE)
std_output, err_output = outputs.communicate()
|