Page 1 of 1

Difficulty running powershell in a for loop due to unquoting and closing of parenthesis

Posted: 17 May 2024 02:41
by shodan
I need to run the following commands in a for loop to capture their output

Code: Select all

powershell -command "Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID | ForEach-Object { $_.PSObject.Properties | ForEach-Object { if ($_.Name -ne 'CimInstanceProperties') { \"$($_.Name)=$($_.Value)\" }}}"
powershell -command "Get-WmiObject -Namespace root\wmi -Class WmiMonitorBasicDisplayParams | Format-List *"
powershell -command "Get-WmiObject -Namespace root\wmi -Class WmiMonitorDescriptorMethods | Format-List *"
powershell -command "Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.Screen]::AllScreens | ForEach-Object { $_ | Format-List * }"
powershell -command "Get-WmiObject Win32_DesktopMonitor | Format-List *"
powershell -command "$monitors = Get-WmiObject -Namespace root\wmi -Class WmiMonitorDescriptorMethods;foreach ($monitor in $monitors) { $edidData = $monitor.WmiGetMonitorRawEEdidV1Block(0); if ($edidData) { if ($edidData.BlockContent) { $edidArray = $edidData.BlockContent; $edidString = [System.BitConverter]::ToString($edidArray); Write-Output $edidString; } else { Write-Output 'No EDID block content found'; } } else { Write-Output 'No EDID data found'; }}"

I am focusing on this line in particular

Code: Select all

powershell -command "Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID | ForEach-Object { $_.PSObject.Properties | ForEach-Object { if ($_.Name -ne 'CimInstanceProperties') { \"$($_.Name)=$($_.Value)\" }}}"

I wish to run it inside a for loop as follows

Code: Select all

for /f "tokens=1,* delims=*" %%a in ('powershell -command "rest of command here" ') do if "[%~2]" NEQ "[]" ( set "%~2.%%a=%%b" ) else ( echo %%a:%%b )

I have tried many permutations but I cannot find something that works !

I really want this to be a one-liner with no temp files

Here is what I tried so far

Code: Select all

for /f "tokens=1,* delims=*" %%a in ('powershell -command "Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID | ForEach-Object { $_.PSObject.Properties | ForEach-Object { if ($_.Name -ne 'CimInstanceProperties') { \"$_.Name=$_.Value\" } } }"') do if "[%~2]" NEQ "[]" ( set "%~2.%%a=%%b" ) else ( echo %%a:%%b )
for /f "tokens=1,* delims==" %%a in ('powershell -Command "Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID ^| ForEach-Object { $_.PSObject.Properties ^| ForEach-Object { if ($_.Name -ne ''CimInstanceProperties'') { ''$($_.Name)=$($_.Value)'' } } }"') do if "[%~2]" NEQ "[]" ( set "%~2.%%a=%%b" ) else ( echo %%a:%%b )
for /f "tokens=1,* delims==" %%a in ('powershell -Command "Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID ^| ForEach-Object { $_.PSObject.Properties ^| ForEach-Object { if ($_.Name -ne ''CimInstanceProperties'') { \"\"$($_.Name)=$($_.Value)\"\" } } } "') do if "[%~2]" NEQ "[]" ( set "%~2.%%a=%%b" ) else ( echo %%a:%%b )
for /f "tokens=1,* delims==" %%a in ('powershell -Command "Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID ^| ForEach-Object { $_.PSObject.Properties ^| ForEach-Object { if ($_.Name -ne \"CimInstanceProperties\") { \"\"$($_.Name)=$($_.Value)\"\" } } } "') do if "[%~2]" NEQ "[]" ( set "%~2.%%a=%%b" ) else ( echo %%a:%%b )
for /f "tokens=1,* delims==" %%a in ('powershell -Command "Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID | ForEach-Object { $_.PSObject.Properties | ForEach-Object { if ($_.Name -ne ''CimInstanceProperties'') { \"\"$($_.Name)=$($_.Value)\"\" } } }"') do if "[%~2]" NEQ "[]" ( set "%~2.%%a=%%b" ) else ( echo %%a:%%b )
for /f "tokens=1,* delims==" %%a in ('powershell -Command "Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID | ForEach-Object { $_.PSObject.Properties | ForEach-Object { if ($_.Name -ne \"CimInstanceProperties\") { \"\"$($_.Name)=$($_.Value)\"\" } } }"') do if "[%~2]" NEQ "[]" ( set "%~2.%%a=%%b" ) else ( echo %%a:%%b )
for /f "tokens=1,* delims==" %%a in ('powershell -command "Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID ^| ForEach-Object { $_.PSObject.Properties ^| ForEach-Object { if ($_.Name -ne ''CimInstanceProperties'') { ''$($_.Name)=$($_.Value)'' }}}"') do if "[%~2]" NEQ "[]" ( set "%~2.%%a=%%b" ) else ( echo %%a:%%b )
for /f "tokens=1,* delims==" %%a in ('powershell -command "Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID ^| ForEach-Object { $_.PSObject.Properties ^| ForEach-Object { if ($_.Name -ne ''CimInstanceProperties'') { if ($_.Value -is [System.Array]) { ''$($_.Name)=''+($_.Value -join '' '')+'' } else { ''$($_.Name)=$($_.Value)'' } } } }"') do if "[%~2]" NEQ "[]" ( set "%~2.%%a=%%b" ) else ( echo %%a:%%b )
for /f "tokens=1,* delims==" %%a in ('powershell -command "Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID | ForEach-Object { $_.PSObject.Properties | ForEach-Object { if ($_.Name -ne ''CimInstanceProperties'') { if ($_.Value -is [System.Array]) { ''$($_.Name)=''+($_.Value -join '' '')+'' } else { ''$($_.Name)=$($_.Value)'' } } }}"') do if "[%~2]" NEQ "[]" ( set "%~2.%%a=%%b" ) else ( echo %%a:%%b )
for /f "tokens=1,* delims==" %%a in ('powershell -command "Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID | ForEach-Object { $_.PSObject.Properties | ForEach-Object { if ($_.Name -ne 'CimInstanceProperties') { \"$($_.Name)=$($_.Value)\" }}}"') do if "[%~2]" NEQ "[]" ( set "%~2.%%a=%%b" ) else ( echo %%a:%%b )
for /f "tokens=1,* delims==" %%a in ('powershell -command "Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID | ForEach-Object { $_.PSObject.Properties | ForEach-Object { if ($_.Name -ne 'CimInstanceProperties') { \"\"$($_.Name)=$($_.Value)\"\" } } }"') do if "[%~2]" NEQ "[]" ( set "%~2.%%a=%%b" ) else ( echo %%a:%%b )
for /f "tokens=1,* delims==" %%a in ('powershell -command "Invoke-Expression \"Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID ^| ForEach-Object { $_.PSObject.Properties ^| ForEach-Object { if ($_.Name -ne 'CimInstanceProperties') { \\\"$($_.Name)=$($_.Value)\\\" } } }\""') do if "[%~2]" NEQ "[]" ( set "%~2.%%a=%%b" ) else ( echo %%a:%%b )
for /f "tokens=1,* delims==" %%a in ('powershell -command "Invoke-Expression \"Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID | ForEach-Object { $_.PSObject.Properties | ForEach-Object { if ($_.Name -ne 'CimInstanceProperties') { \\\"$($_.Name)=$($_.Value)\\\" } } }\""') do if "[%~2]" NEQ "[]" ( set "%~2.%%a=%%b" ) else ( echo %%a:%%b )
for /f "usebackq tokens=1,* delims==" %%a in (`powershell -Command "Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID ^| ForEach-Object { $_.PSObject.Properties ^| ForEach-Object { if ($_.Name -ne 'CimInstanceProperties') { '^"$($_.Name)=$($_.Value)'^" } } }"`) do if "[%~2]" NEQ "[]" ( set "%~2.%%a=%%b" ) else ( echo %%a:%%b )
for /f "usebackq tokens=1,* delims==" %%a in (`powershell -Command "Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID ^| ForEach-Object { $_.PSObject.Properties ^| ForEach-Object { if ($_.Name -ne 'CimInstanceProperties') { ^"$($_.Name)=$($_.Value)^" } } }"`) do if "[%~2]" NEQ "[]" ( set "%~2.%%a=%%b" ) else ( echo %%a:%%b )
for /f "usebackq tokens=1,* delims==" %%a in (`powershell -Command "Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID | ForEach-Object { $_.PSObject.Properties | ForEach-Object { if ($_.Name -ne 'CimInstanceProperties') { \"\$($_.Name)=$($_.Value)\" } } }"`) do if "[%~2]" NEQ "[]" ( set "%~2.%%a=%%b" ) else ( echo %%a:%%b )

The issue is inside of this part

Code: Select all

{ \"$($_.Name)=$($_.Value)\" }
Batch does not recognize the powershell escaping of the doublequote \"
So it thinks the rest is unquoted. Then the parenthesis gets closed.
Strangely, we are still inside the single quoting at this point. But it seem that still closes this part of the for loop early

Code: Select all

for %%a in () <-- 

Re: Difficulty running powershell in a for loop due to unquoting and closing of parenthesis

Posted: 17 May 2024 03:59
by miskox
Wouldn't it be easier for you to use a temporary file and process this temporary file with FOR loop?

Saso

Re: Difficulty running powershell in a for loop due to unquoting and closing of parenthesis

Posted: 17 May 2024 16:13
by penpen
You have to escape the characters, that are not encapsulated within double quotes, which in the example should be everything colored red:
powershell -command "Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID | ForEach-Object { $_.PSObject.Properties | ForEach-Object { if ($_.Name -ne 'CimInstanceProperties') { \"$($_.Name)=$($_.Value)\" }}}"

So the following might help you (untested; i changed the content of the for loop so you can use that as a test whether or not i escaped all relevant characters):

Code: Select all

for /f "tokens=1,* delims=*" %%a in ('powershell -command "Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID | ForEach-Object { $_.PSObject.Properties | ForEach-Object { if ($_.Name -ne 'CimInstanceProperties') { \"$($_.Name^)=$($_.Value^)\" }}}"') do (
	echo(%%~a   -----   %%~b
)

penpen

Re: Difficulty running powershell in a for loop due to unquoting and closing of parenthesis

Posted: 17 May 2024 19:07
by shodan
That's a bingo

Thank you @penpen

Code: Select all

Active   -----   True
InstanceName   -----   DISPLAY\DELD092\4&dead9271&0&UID21beef_0
ManufacturerName   -----   68 69 76 0 0 0 0 0 0 0 0 0 0 0 0 0
ProductCodeID   -----   68 48 57 50 0 0 0 0 0 0 0 0 0 0 0 0
SerialNumberID   -----   57 80 DE AD BE EF 52 80 DE AD BE EF 0 0 0 0
UserFriendlyName   -----   68 69 76 76 32 80 49 57 49 55 83 0 0
UserFriendlyNameLength   -----   13
WeekOfManufacture   -----   12
YearOfManufacture   -----   2018
PSComputerName   -----
CimClass   -----   root/wmi:WmiMonitorID
CimSystemProperties   -----   Microsoft.Management.Infrastructure.CimSystemProperties
Active   -----   True
InstanceName   -----   DISPLAY\DELD092\4&dead9271&0&UID21beef_0
ManufacturerName   -----   68 69 76 0 0 0 0 0 0 0 0 0 0 0 0 0
ProductCodeID   -----   68 48 57 50 0 0 0 0 0 0 0 0 0 0 0 0
SerialNumberID   -----   57 80 DE AD BE EF 52 80 DE AD BE EF 0 0 0 0
UserFriendlyName   -----   68 69 76 76 32 80 49 57 49 55 83 0 0
UserFriendlyNameLength   -----   13
WeekOfManufacture   -----   12
YearOfManufacture   -----   2018
PSComputerName   -----
CimClass   -----   root/wmi:WmiMonitorID
CimSystemProperties   -----   Microsoft.Management.Infrastructure.CimSystemProperties
Active   -----   True
InstanceName   -----   DISPLAY\DELD092\4&dead9271&0&UID21beef_0
ManufacturerName   -----   68 69 76 0 0 0 0 0 0 0 0 0 0 0 0 0
ProductCodeID   -----   68 48 57 50 0 0 0 0 0 0 0 0 0 0 0 0
SerialNumberID   -----   57 80 DE AD BE EF 52 80 DE AD BE EF 0 0 0 0
UserFriendlyName   -----   68 69 76 76 32 80 49 57 49 55 83 0 0
UserFriendlyNameLength   -----   13
WeekOfManufacture   -----   12
YearOfManufacture   -----   2018
PSComputerName   -----
CimClass   -----   root/wmi:WmiMonitorID
CimSystemProperties   -----   Microsoft.Management.Infrastructure.CimSystemProperties