Search code examples
c#wmi

WMI Win32_NetworkAdapterConfiguration and SetDNSSuffixSearchOrder method


I need to append DNS suffixes from a C# application:

based on this WORKING VB Script:

On Error Resume Next

strComputer = "."
arrNewDNSSuffixSearchOrder = Array("my.first.suffix", "my.second.suffix")

Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colNicConfigs = objWMIService.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True")

For Each objNicConfig In colNicConfigs
  strDNSHostName = objNicConfig.DNSHostName
Next
WScript.Echo VbCrLf & "DNS Host Name: " & strDNSHostName

For Each objNicConfig In colNicConfigs
  WScript.Echo VbCrLf & "  Network Adapter " & objNicConfig.Index & VbCrLf & objNicConfig.Description & VbCrLf & "    DNS Domain Suffix Search Order - Before:"
  If Not IsNull(objNicConfig.DNSDomainSuffixSearchOrder) Then
    For Each strDNSSuffix In objNicConfig.DNSDomainSuffixSearchOrder
      WScript.Echo "      " & strDNSSuffix
    Next
  End If
Next

WScript.Echo VbCrLf & String(80, "-")

Set objNetworkSettings = objWMIService.Get("Win32_NetworkAdapterConfiguration")
intSetSuffixes = objNetworkSettings.SetDNSSuffixSearchOrder(arrNewDNSSuffixSearchOrder)
If intSetSuffixes = 0 Then
  WScript.Echo VbCrLf & "Replaced DNS domain suffix search order list."
ElseIf intSetSuffixes = 1 Then
  WScript.Echo VbCrLf & "Replaced DNS domain suffix search order list." & _
   VbCrLf & "    Must reboot."
Else
  WScript.Echo VbCrLf & "Unable to replace DNS domain suffix " & _
   "search order list."
End If

WScript.Echo VbCrLf & String(80, "-")

Set colNicConfigs = objWMIService.ExecQuery _
 ("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True")
For Each objNicConfig In colNicConfigs
  WScript.Echo VbCrLf & "  Network Adapter " & objNicConfig.Index & VbCrLf & objNicConfig.Description & VbCrLf & "    DNS Domain Suffix Search Order - After:"
  If Not IsNull(objNicConfig.DNSDomainSuffixSearchOrder) Then
    For Each strDNSSuffix In objNicConfig.DNSDomainSuffixSearchOrder
      WScript.Echo "      " & strDNSSuffix
    Next
  End If
Next

I ended up with this NON WORKING C# code:

using System;
using System.Diagnostics;
using System.Management;

namespace ChangeDnsSuffix
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] aSuffix = { "my.first.suffix", "my.second.suffix" };
            Int32 ret = SetDNSSuffixSearchOrder(aSuffix);
        }

        private static Int32 SetDNSSuffixSearchOrder(string[] DNSDomainSuffixSearchOrder)
        {
            try
            {
                ManagementPath mp = new ManagementPath((@"\\.\root\cimv2:Win32_NetworkAdapterConfiguration"));

                InvokeMethodOptions Options = new InvokeMethodOptions();
                Options.Timeout = new TimeSpan(0, 0, 10);
                ManagementClass WMIClass = new ManagementClass("Win32_NetworkAdapterConfiguration");
                ManagementBaseObject InParams = WMIClass.GetMethodParameters("SetDNSSuffixSearchOrder");
                InParams["DNSDomainSuffixSearchOrder"] = DNSDomainSuffixSearchOrder;

                ManagementBaseObject OutParams = null;
                OutParams = InvokeMethod(mp.Path,"SetDNSSuffixSearchOrder", InParams, Options);

                Int32 numericResult = Convert.ToInt32(OutParams["ReturnValue"]);
                return numericResult;

            }
            catch (Exception exception)
            {
                Debug.WriteLine(exception.Message);
                return 0;
            }
        }

        public static ManagementBaseObject InvokeMethod(string ObjectPath, string MethodName, ManagementBaseObject InParams, InvokeMethodOptions Options)
        {
            ManagementObject WMIObject = new ManagementObject(ObjectPath);
            ManagementBaseObject OutParams = WMIObject.InvokeMethod(MethodName, InParams, Options);

            if (InParams != null)
            {
                InParams.Dispose();
            }

            return OutParams;
        }  
    }
}

I tried an changed a lot in the code. once the error was 'Invalid Method', once the code killed my VS Instance, currently the error is:

Operation is not valid due to the current state of the object.

I did run the compiled application and visual studio elevated and not-elevated, no difference.

help's really appreciated!

Christian


based on what manuchao contributed, i have now:

using System;
using System.Diagnostics;
using System.Management;
using System.Management.Instrumentation;
using System.Collections.Generic;

namespace ChangeDnsSuffix
{
    class Program
    {
        static void Main(string[] args)
        {
            foreach (ManagementObject mo in GetSystemInformation())
            {
                mo.SetPropertyValue("DNSDomainSuffixSearchOrder", new object[] { "suffix.com" });
                mo.Put();
            }
        }

        private static IEnumerable<ManagementObject> GetSystemInformation()
        {
            ManagementObjectCollection collection = null;
            ManagementScope Scope = new ManagementScope(String.Format("\\\\{0}\\root\\cimv2", "."));

            try
            {
                SelectQuery query = new SelectQuery("select * from Win32_NetworkAdapterConfiguration");
                Scope.Connect();
                ManagementObjectSearcher searcher = new ManagementObjectSearcher(Scope, query);
                collection = searcher.Get();
            }
            catch (ManagementException ex)
            {
                Console.WriteLine(ex.Message);
            }
            catch (UnauthorizedAccessException ex)
            {
                throw new ArgumentException(ex.Message);
            }

            if (collection == null) { yield break; }

            foreach (ManagementObject obj in collection)
            {
                yield return obj;
            }
        }

        public IEnumerable<PropertyData> GetPropertiesOfManagmentObj(ManagementObject obj)
        {
            var properties = obj.Properties;
            foreach (PropertyData item in properties)
            {
                yield return item;
            }
            yield break;
        }
    }
}

results in:

'Provider is not capable of the attempted operation'


Solution

  • I made some tweaks, and the following method successfully sets DNS search suffixes on my machine:

    public static Int32 SetDNSSuffixSearchOrder(string[] DNSDomainSuffixSearchOrder)
    {
        try
        {
            var options = new InvokeMethodOptions();
            options.Timeout = new TimeSpan(0, 0, 10);
    
            var wmiClass = new ManagementClass("Win32_NetworkAdapterConfiguration");
            var inParams = wmiClass.GetMethodParameters("SetDNSSuffixSearchOrder");
    
            inParams["DNSDomainSuffixSearchOrder"] = DNSDomainSuffixSearchOrder;
    
            var outParams = wmiClass.InvokeMethod("SetDNSSuffixSearchOrder", inParams, options);
    
            var numericResult = Convert.ToInt32(outParams["ReturnValue"]);
            return numericResult;
    
        }
        catch (Exception exception)
        {
            Debug.WriteLine(exception.Message);
            return 0;
        }
    }