/build/static/layout/Breadcrumb_cap_w.png

KACE Product Support Question


Custom Inventory Rule Escaping Quotes

05/23/2013 2896 views

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

Comments


All Answers

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!

Answered 05/23/2013 by: dimitris
Purple 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.

Answered 05/24/2013 by: Magnum_
Orange Senior Belt

 
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