How do i execute powershell command's with pipes in python?

import subprocess
subprocess.Popen('powershell.exe [Get-ADPrincipalGroupMembership %USERNAME% | select name]')
os.system('powershell.exe Get-ADPrincipalGroupMembership %USERNAME% | select name]')

I have tried bot of these with varying attempts to escape each character, exclude each character etc. I'm lost.

All I want to do is have a function in python that runs Get-ADPrincipalGroupMembership, Pipes it to select then pipes it to out-file so I can store it. But if I include a pipe in the command the window will always close upon opening and no output is produced.

I can't tell what's wrong since I can't see what the PS window is doing and I don't know why it specifically has an issue with pipes.

thanks,

1 Answer

You are mixing Python/ cmd.exe variable names in a PowerShell.

PowerShell has no idea what %USENAME% is and will error out, as it is not a PowerShell construct.

You should absolutely see what the PowerShell.exe console is doing because you are using an external to call Powershell.exe and that is a completely separate session start than the python session you are in.

Thus you'd see not only the python console but the PowerShell console should popup as well, and if you want to see what it is doing, you need to use either the pause, -wait or noexit switches. See the PowerShell help file for more details.

PowerShell automatic variable requires you to specify the user name like this:

$env:USERNAME

not this:

%USERNAME%

PowerShell has many automatic variables that come from the Env drive.

Get-PSDrive | Format-Table -AutoSize
<#
# Results
Name Used (GB) Free (GB) Provider Root CurrentLocation
---- --------- --------- -------- ---- ---------------
...
Env Environment
...
#>
Get-ChildItem -Path 'env:\'
<#
Name Value
---- -----
ALLUSERSPROFILE C:\ProgramData
APPDATA C:\Users\Daniel\AppData\Roaming
CommonProgramFiles C:\Program Files\Common Files
CommonProgramFiles(x86) C:\Program Files (x86)\Common Files
CommonProgramW6432 C:\Program Files\Common Files
COMPUTERNAME LP70
ComSpec C:\Windows\system32\cmd.exe
DriverData C:\Windows\System32\Drivers\DriverData
HOMEDRIVE C:
HOMEPATH \Users\Daniel
LOCALAPPDATA C:\Users\Daniel\AppData\Local
LOGONSERVER \\LP70
MSMPI_BENCHMARKS C:\Program Files\Microsoft MPI\Benchmarks\
MSMPI_BIN C:\Program Files\Microsoft MPI\Bin\
NUMBER_OF_PROCESSORS 8
OneDrive C:\Users\Daniel\OneDrive
OneDriveConsumer C:\Users\Daniel\OneDrive
OS Windows_NT
Path C:\Program Files\Microsoft MPI\Bin\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System...
PATHEXT .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL
POWERSHELL_DISTRIBUTION_CHA... MSI:Windows 10 Pro
PROCESSOR_ARCHITECTURE AMD64
PROCESSOR_IDENTIFIER Intel64 Family 6 Model 94 Stepping 3, GenuineIntel
PROCESSOR_LEVEL 6
PROCESSOR_REVISION 5e03
ProgramData C:\ProgramData
ProgramFiles C:\Program Files
ProgramFiles(x86) C:\Program Files (x86)
ProgramW6432 C:\Program Files
PSModulePath C:\Users\Daniel\Documents\WindowsPowerShell\Modules;C:\Program Files\WindowsPowerShell\Modules;C:\Windows\system32\WindowsPowerShell\v1.0\Modules;C:\Prog...
PUBLIC C:\Users\Public
PyCharm Community Edition C:\Program Files\JetBrains\PyCharm Community Edition 2019.2.4\bin;
SystemDrive C:
SystemRoot C:\Windows
TEMP C:\Users\Daniel\AppData\Local\Temp
TMP C:\Users\Daniel\AppData\Local\Temp
USERDOMAIN LP70
USERDOMAIN_ROAMINGPROFILE LP70
USERNAME Daniel
USERPROFILE C:\Users\Daniel
windir C:\Windows
#>

You get to each for those by their variable name:

$env:USERNAME
$env:USERPROFILE
$env:COMPUTERNAME

It may be that you are really good a Python, but why are you using Python to do PowerShell stuff, vs using PowerShell directly, especially when trying to use ADDS (RSAT) cmdlets? Unless you have Windows RSAT installed/enabled on your host

Remote Server Administration Tools for Windows 7 with Service Pack 1 (SP1)

Install RSAT for Windows 10 1809 and 1903 and 1909 automated

Use PowerShell Active Directory Cmdlets Without Installing Any Software

or you have made an implicit/explicit Powershell remote connection

about_Remote - PowerShell | Microsoft Docs

PowerShell implicit remoting active directory

...to a DC (or another host that has the RSAT tools), to proxy those cmdlets to you PowerShell session, then they are not even available for use.

You are not using the cmdlet syntax property as well.

Get-ADPrincipalGroupMembership

This leads one to assume that you are new to ADDS with PowerShell, which is fine but should send you to get ramped up on both natively, before trying to merge with an outside language.

Bounce over to Youtube search for

So, this is what I am illustrating in my other comments. and why if you are trying to spin this off a Python session, vs directly from PowerShell, that it can be a bit of a challenge, because of what Python needs to run and call PowerShell for Powershell to have the resources to run a given cmdlet. I do not have Python in an environment, nor do I need it, to test this. I do PSremting every day, as do many in the industry and it works just fine.

# Change this...
import subprocess
subprocess.Popen('powershell.exe [Get-ADPrincipalGroupMembership %USERNAME% | select name]')
os.system('powershell.exe Get-ADPrincipalGroupMembership %USERNAME% | select name]')
# To this, Impot the process
import subprocess
# Use a subprocess to start powershel.exe, which creates an implicit PowerShell remote session to a DC to proxy the RSAT/ADDS cmdlets to get group information
subprocess.call(["C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\powershell.exe", "$DCSssion = New-PSSession –ComputerName 'YourDCName'", "Invoke-Command –Session $DCsession –ScriptBlock {Get-ADPrincipalGroupMembership -Identity $env:USERNAME | Select-Object -Property Name}"])

Point of note: To invoke commands on a remote host you must be an admin on that remote host.

***Update based on your thread ***

I can't handle the data as nicely and it's clunky as hell but it works

PowerShell returns objects, by design/default, not strings. So, when you run stuff like this...

Get-ADPrincipalGroupMembership -Identity $ntaccount1 |
select-Object -Property Name |
Where-Object {$PSItem.name -like '*certain string*' } |
Sort Name

All you get back is one property object. Name sorted ascending. You could also do this if all you wanted was one property...

(Get-ADPrincipalGroupMembership -Identity $ntaccount1).Name |
Where-Object {$PSItem.name -like '*certain string*' } |
Sort-Object -Property Name

Of course, if you wanted to see all properties of a single user object...

Get-ADPrincipalGroupMembership -Identity '*'|
select-Object -First 1
select-Object -Property '*'

If you put this in a variable, you just dot reference each property

$ADpgm = Get-ADPrincipalGroupMembership -Identity '*' |
select-Object -First 1
select-Object -Property '*'
# See all properties and methods on an object
$ADpgm | Get-Member
# Get one property value
$ADpgm.Name
# Get specifics for a module, cmdlet, or function
(Get-Command -NameGet-ADPrincipalGroupMembership).Parameters
(Get-Command -NameGet-ADPrincipalGroupMembership).Parameters.Keys
Get-help -NameGet-ADPrincipalGroupMembership -Examples
Get-help -NameGet-ADPrincipalGroupMembership -Full
Get-help -NameGet-ADPrincipalGroupMembership -Online
7

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like