/build/static/layout/Breadcrumb_cap_w.png

Custom Inventory Rule Escaping Quotes

I have the following Custom Inventory Rule:

ShellCommandTextReturn(powershell.exe $diskdrive = gwmi win32_diskdrive;foreach($drive in $diskdrive){if($drive.model -match 'SSD'){$ssd='SSD'}else{$ssd='HDD'}$partitions=gwmi -Query """ASSOCIATORS OF {Win32_DiskDrive.DeviceID=`"""$($drive.DeviceID.replace('\','\\'))`"""} WHERE AssocClass=Win32_DiskDriveToDiskPartition"""; foreach($part in $partitions){$vols=gwmi -Query """ASSOCIATORS OF {Win32_DiskPartition.DeviceID=`"""$($part.DeviceID)`"""} WHERE AssocClass = Win32_LogicalDiskToPartition""";foreach($vol in $vols){out-host -InputObject """$ssd $($vol.name)""";}}})

If you strip out the just the ShellCommandTextReturn( and the closing ) the command runs fine in cmd.exe. It does not work in the CIR. 

Log:

 [Thu May 23 11:11:45 2013] [CDeployController::ExecuteCustomInventoryRule] statement result: ;7150:VHJ1ZQ0K%TEXT, TRUE
[Thu May 23 11:11:45 2013] [CDeployController::ExecuteCustomInventoryRule] issuing rule [ShellCommandTextReturn(powershell.exe $diskdrive = gwmi win32_diskdrive;foreach($drive in $diskdrive){if($drive.model -match 'SSD'){$ssd='SSD'}else{$ssd='HDD'}$partitions=gwmi -Query """ASSOCIATORS OF {Win32_DiskDrive.DeviceID=`"""$($drive.DeviceID.replace('\','\\'))`"""} WHERE AssocClass=Win32_DiskDriveToDiskPartition"""; foreach($part in $partitions){$vols=gwmi -Query """ASSOCIATORS OF {Win32_DiskPartition.DeviceID=`"""$($part.DeviceID)`"""} WHERE AssocClass = Win32_LogicalDiskToPartition""";foreach($vol in $vols){out-host -InputObject """$ssd $($vol.name)""";}}});]
[Thu May 23 11:11:45 2013] haveTokenLsaPriv returning: 1
[Thu May 23 11:11:45 2013] KLaunchProcess: Call CreateProcess to launch 'KLaunch.exe . -wait -hide -stdout "C:\Windows\TEMP\dkl720B.tmp" powershell.exe $diskdrive = gwmi win32_diskdrive;foreach($drive in $diskdrive){if($drive.model -match 'SSD'){$ssd='SSD'}else{$ssd='HDD'}$partitions=gwmi -Query "\"\"""\"ASSOCIATORS OF {Win32_DiskDrive.DeviceID=`\"""\"\""$($drive.DeviceID.replace('\','\\'))`"\"\"""\"} WHERE AssocClass=Win32_DiskDriveToDiskPartition\"""\"\""; foreach($part in $partitions){$vols=gwmi -Query "\"\"""\"ASSOCIATORS OF {Win32_DiskPartition.DeviceID=`\"""\"\""$($part.DeviceID)`"\"\"""\"} WHERE AssocClass = Win32_LogicalDiskToPartition\"""\"\"";foreach($vol in $vols){out-host -InputObject "\"\"""\"$ssd $($vol.name)\"""\"\"";}}}':
[Thu May 23 11:11:45 2013] KLaunchProcess: Wait for process to complete
[Thu May 23 11:11:48 2013] KLaunchProcess: process completed status=1
[Thu May 23 11:11:48 2013] [CDeployController::ExecuteCustomInventoryRule] statement result: "", FALSE

It appears to be doing automatic escaping for some of the quotes, but I can't figure out how it is determining what to escape. 

I have also tried escaping the quotes with a \ manually and it fails as well. 

ShellCommandTextReturn(powershell.exe $diskdrive = gwmi win32_diskdrive;foreach($drive in $diskdrive){if($drive.model -match 'SSD'){$ssd='SSD'}else{$ssd='HDD'}$partitions=gwmi -Query \"\"\"ASSOCIATORS OF {Win32_DiskDrive.DeviceID=`\"\"\"$($drive.DeviceID.replace('\','\\'))`\"\"\"} WHERE AssocClass=Win32_DiskDriveToDiskPartition\"\"\"; foreach($part in $partitions){$vols=gwmi -Query \"\"\"ASSOCIATORS OF {Win32_DiskPartition.DeviceID=`\"\"\"$($part.DeviceID)`\"\"\"} WHERE AssocClass = Win32_LogicalDiskToPartition\"\"\";foreach($vol in $vols){out-host -InputObject \"\"\"$ssd $($vol.name)\"\"\";}}})

Log:

[Thu May 23 11:46:21 2013] [CDeployController::ExecuteCustomInventoryRule] statement result: ;7150:VHJ1ZQ0K%TEXT, TRUE
[Thu May 23 11:46:21 2013] [CDeployController::ExecuteCustomInventoryRule] issuing rule [ShellCommandTextReturn(powershell.exe $diskdrive = gwmi win32_diskdrive;foreach($drive in $diskdrive){if($drive.model -match 'SSD'){$ssd='SSD'}else{$ssd='HDD'}$partitions=gwmi -Query \"\"\"ASSOCIATORS OF {Win32_DiskDrive.DeviceID=`\"\"\"$($drive.DeviceID.replace('\','\\'))`\"\"\"} WHERE AssocClass=Win32_DiskDriveToDiskPartition\"\"\"; foreach($part in $partitions){$vols=gwmi -Query \"\"\"ASSOCIATORS OF {Win32_DiskPartition.DeviceID=`\"\"\"$($part.DeviceID)`\"\"\"} WHERE AssocClass = Win32_LogicalDiskToPartition\"\"\";foreach($vol in $vols){out-host -InputObject \"\"\"$ssd $($vol.name)\"\"\";}}});]
[Thu May 23 11:46:21 2013] haveTokenLsaPriv returning: 1
[Thu May 23 11:46:21 2013] KLaunchProcess: Call CreateProcess to launch 'KLaunch.exe . -wait -hide -stdout "C:\Windows\TEMP\dkl1E03.tmp" powershell.exe $diskdrive = gwmi win32_diskdrive;foreach($drive in $diskdrive){if($drive.model -match 'SSD'){$ssd='SSD'}else{$ssd='HDD'}$partitions=gwmi -Query "\"\"""\"ASSOCIATORS OF {Win32_DiskDrive.DeviceID=`\"""\"\""$($drive.DeviceID.replace('\','\\'))`"\"\"""\"} WHERE AssocClass=Win32_DiskDriveToDiskPartition\"""\"\""; foreach($part in $partitions){$vols=gwmi -Query "\"\"""\"ASSOCIATORS OF {Win32_DiskPartition.DeviceID=`\"""\"\""$($part.DeviceID)`"\"\"""\"} WHERE AssocClass = Win32_LogicalDiskToPartition\"""\"\"";foreach($vol in $vols){out-host -InputObject "\"\"""\"$ssd $($vol.name)\"""\"\"";}}}':
[Thu May 23 11:46:21 2013] KLaunchProcess: Wait for process to complete
[Thu May 23 11:46:24 2013] KLaunchProcess: process completed status=1
[Thu May 23 11:46:24 2013] [CDeployController::ExecuteCustomInventoryRule] statement result: "", FALSE

I just can't see where the escape sequence needs to happen.  Any help would be appreciated.  Thanks.


0 Comments   [ + ] Show comments

Answers (2)

Posted by: dimitris 10 years ago
Purple Belt
0

I know one of these two problems fixed my concern.

Either the ` or the $($variable) were causing problems.  I resolved the need for powershell escaping by creating a powershell quote variable, $q = '"""';  I resolved the $($variable) by doing some matching and other variable manipulation to remove the need for the $().

Hope this helps someone else!

Posted by: Magnum_ 10 years ago
Orange Senior Belt
0

Looks like a good solution, but I don't think it improves the readability of the script :D

I think that the interface for these kind of rules should be improved.

But nevertheless : When I need such a "complicated" query, I just write the info to a registry key or file using a KACE script, and pick up the values from there with a RegistryValueReturn(registryPath, name, type) 

That gives me a more granular control on the timing and frequency. Some things just don't need to be updated at every inventory update.

Don't be a Stranger!

Sign up today to participate, stay informed, earn points and establish a reputation for yourself!

Sign up! or login

Share

 
This website uses cookies. By continuing to use this site and/or clicking the "Accept" button you are providing consent Quest Software and its affiliates do NOT sell the Personal Data you provide to us either when you register on our websites or when you do business with us. For more information about our Privacy Policy and our data protection efforts, please visit GDPR-HQ