1

I'm trying to execute a WMI query that lists all the subdirectories in a directory on a different network-attached computer (server), but it's failing with a System.Management.ManagementException "Invalid query" exception.

I am practically certain that this issue is due to the directory name containing left- and/or right-curly braces ({, }).

UPDATE: I've determined that the issue is not the left-curly brace, but the right-curly brace.

I've tried various things to escape these characters, but nothing seems to work.

Below is a contrived example that fails with "Invalid query" every time.

using System;
using System.Management;

public static class Program
{
    public static void Main()
    {
        const string username = @"Domain\User";
        const string password = @"Password";
        const string server = @"Server";

        const string query = @"Associators of {"
                             + @"Win32_Directory.Name='"
                             + @"c:\program files (x86)\a_test}"
                             + @"'} "
                             + @"Where AssocClass = Win32_Subdirectory ResultRole = PartComponent";

        var options = new ConnectionOptions { Username = username, Password = password };
        var wmiScope = new ManagementScope(@"\\" + server + @"\root\cimv2", options);
        var wmiQuery = new ObjectQuery(query);
        var searcher = new ManagementObjectSearcher(wmiScope, wmiQuery);
        var searchResults = searcher.Get();

        foreach (var searchResult in searchResults)
        {
            var subPath = searchResult.GetPropertyValue("Name").ToString();
            var system = Convert.ToBoolean(searchResult.GetPropertyValue("System"));
            Console.WriteLine($"subPath = {subPath}; system = {system}");
        }
    }
}

For what it's worth, the code is running on a Windows 10 machine querying a Windows 2008 R2 SP1 server (yes, it's scheduled for demolition).

Thanks!

STLDev
  • 5,950
  • 25
  • 36
  • Can [this](https://stackoverflow.com/questions/23827199/escaping-strings-when-using-wmic) help? – vasily.sib Mar 11 '19 at 05:16
  • @vasily.sib - The question you point suggests escaping with a caret (`^`) character. I've tried escaping the curly braces with back slash, forward slash, another curly brace, caret (`^`) - none work. – STLDev Mar 11 '19 at 05:27
  • its looks like that you have extra closing brackets ( **}** ) , try to comment out the 3rd row in your query: `+ @"'} "` – styx Mar 11 '19 at 09:44
  • @styx - those are there to escape the curly braces from C# string interpolation. – STLDev Mar 11 '19 at 10:22
  • If you 'unfold' your query you get `Associators of {Win32_Directory.Name='c:\program files (x86)\a_test}'} Where AssocClass = Win32_Subdirectory ResultRole = PartComponent` and as you can see you have 1 opening brackets and 2 closing brackets – styx Mar 12 '19 at 13:25
  • @styx...that `}` at the end of `a_test}` is last character of the name of that directory. It is the very character that I'm attempting to escape. So, there are no unbalanced brackets. – STLDev Mar 13 '19 at 05:44

1 Answers1

3

This appears to be a quirk of the Associators of parsing. To fix this, use the double quote syntax for strings rather than the single quote syntax (taking care to escape backslashes, since this is required for the double quote approach):

const string query = @"Associators of {"
                     + @"Win32_Directory.Name="""
                     + @"c:\\program files (x86)\\a_test}"
                     + @"""} "
                     + @"Where AssocClass = Win32_Subdirectory ResultRole = PartComponent";
Jeroen Mostert
  • 27,176
  • 2
  • 52
  • 85
  • Thank you! I felt very strongly that this had to be a parsing bug, but couldn't get anything to work! – STLDev Mar 13 '19 at 05:38
  • Quick followup question: What if both } and "are present in a Associators query? Such as in ObjectIDs of MSFT_VirtualDisk objects. How to quote the " ? Great answer :) – Johannes Thoma May 17 '22 at 17:33
  • @JohannesThoma: I suspect escaping the double quotes with a backslash (`\"`) should work (but I can't test at the moment). – Jeroen Mostert May 17 '22 at 17:34
  • @JeroenMostert: Thank you yes the backslash worked. So preparing for quoting can be done with `string quoted_object_id = vdisk["ObjectId"].ToString().Replace(@"\", @"\\").Replace(@"""", @"\""");` (vdisk being a MSFT_VirtualDisk object) – Johannes Thoma May 24 '22 at 14:11