How to get registry and file exclusions from UWF u

2019-07-29 04:52发布

问题:

I want to get all registry exclusion and file exclusion from UWF, using the WMI.

I've already tried to invoke GetExclusions methods from UWF_RegistryFilter class but of no luck.

I am looking forward to a working sample code, thanks in advance for any help!

回答1:

The difficult part is to read the out parameters from the method result. There is no appropriate documentation available on Microsoft website and it's difficult to guess how ManagementBaseObject can be utilized for reading the out parameters.

In order to reach to a solution, I tried to develop an understanding of how WMI makes use of out parameters based on other well-documented wmi samples. Please use the C# code below, I hope it helps:

public static void GetRegistryExclusions()
    {

        ManagementScope scope = new ManagementScope(@"root\standardcimv2\embedded");
        using (ManagementClass mc = new ManagementClass(scope.Path.Path, "UWF_RegistryFilter",
        null))
        {
            ManagementObjectCollection moc = mc.GetInstances();
            foreach (ManagementObject mo in moc)
            {
                ManagementBaseObject[] result = (ManagementBaseObject[])mo.InvokeMethod("GetExclusions", null, null).Properties["ExcludedKeys"].Value;

                if (result != null)
                {
                    foreach (var r in result)
                    {
                        Console.WriteLine(r.GetPropertyValue("RegistryKey"));
                    }
                }
            }
        }
    }

Note/Request Request someone with 1500 reputation to create and link following tags so that it becomes easier for people like me to request solutions/answer questions on stackoverflow.

  1. UWF
  2. UWFMGR


回答2:

Found Manoj's answer only after I figured it out myself from a hint on a microsoft forum, when I wanted to put my code on SO. Therefore adding keywords Unified Write Filter and UWF_Volume (does it work like this?).

I used a slightly shorter syntax to access the properties, and also return the excluded files as the OP asked. I tried to make it as robust as possible, as it seems that there are some invalid volume entries. If someone has a clue what they are, please let me know.

public static string GetFilterDetail()
{
  string details = "";
  string detailsCurrent = "";
  string detailsNext = "";
  try
  {
    // Get WMI provider for UWF
    var scope = new ManagementScope(@"\\localhost\root\StandardCimv2\embedded");
    var managementPath = scope.Path.Path;
    using (ManagementClass volumeFilterClass = new ManagementClass(managementPath, "UWF_Volume", null))
    {
      var volumeFilters = volumeFilterClass?.GetInstances();
      if (volumeFilters != null && volumeFilters.Count > 0)
      {
        foreach (ManagementObject volumeFilter in volumeFilters)
        {
          if (volumeFilter != null)
          {
            // Now we have access to the Volume's WMI provider class

            // First check if this is a valid Volume instance, as from trial and error it seems that is not always the case.
            // Some invalid/undocumented instances throw a Not Found ManagementException on the GetExclusions method.
            // Some also throw a NullReferenceException on mo.GetPropertyValue("Protected"), but that covers less cases.
            bool isInstanceValid = true;
            try
            {
              volumeFilter.InvokeMethod("GetExclusions", null, null);
            }
            catch (ManagementException ex)
            {
              if (ex.Message.ToLower().Contains("not found"))
                isInstanceValid = false;
              else throw ex;
            }

            if (isInstanceValid)
            {
              bool currentSession = ((bool)volumeFilter.GetPropertyValue("CurrentSession"));
              string driveLetter = (string)volumeFilter.GetPropertyValue("DriveLetter");
              bool isProtected = ((bool)volumeFilter.GetPropertyValue("Protected"));
              string detail = "Volume " + driveLetter + " is " + (isProtected ? "protected" : "not protected") + ".\n";
              detail += "Excluded files:\n";

              ManagementBaseObject outParams = volumeFilter.InvokeMethod("GetExclusions", null, null);
              if (outParams != null)
              {
                var excludedItems = (ManagementBaseObject[])outParams["ExcludedFiles"];
                if (excludedItems != null)
                {
                  foreach (var excludedItem in excludedItems)
                  {
                    detail += "    " + driveLetter + excludedItem["FileName"] + "\n";
                  }
                }
                else detail += "    [No excluded files]\n";
              }

              if (currentSession)
                detailsCurrent += detail;
              else
                detailsNext += detail;
            }
          }
        }
      }
    }
    using (ManagementClass registryFilterClass = new ManagementClass(managementPath, "UWF_RegistryFilter", null))
    {
      var registryFilters = registryFilterClass?.GetInstances();
      if (registryFilters != null && registryFilters.Count > 0)
      {
        foreach (ManagementObject registryFilter in registryFilters)
        {
          if (registryFilter != null)
          {
            // Now we have access to the RegistryFilter's WMI provider class

            bool currentSession = ((bool)registryFilter.GetPropertyValue("CurrentSession"));
            string detail = "Excluded registry keys:\n";

            ManagementBaseObject outParams = registryFilter.InvokeMethod("GetExclusions", null, null);
            if (outParams != null)
            {
              var excludedItems = (ManagementBaseObject[])outParams["ExcludedKeys"];
              if (excludedItems != null)
              {
                foreach (var excludedItem in excludedItems)
                {
                  detail += "    " + excludedItem["RegistryKey"] + "\n";
                }
              }
              else detail += "    [No excluded registry keys]\n";
            }

            if (currentSession)
              detailsCurrent += detail;
            else
              detailsNext += detail;
          }
        }
      }
    }
  }
  catch (Exception ex)
  {
    details += ex.ToString();
  }

  details += "\nNOTE: These settings are only active if the Write Filter is Enabled\n"
          + "\nCURRENT SETTINGS:\n" + detailsCurrent
          + "\nNEXT SETTINGS: (after next reboot)\n" + detailsNext;

  return details;
}

Example output: