Using WMI to create active directory dns zones - c#

I'm using the following code to create a DNS zone:
ManagementClass zoneObj = new ManagementClass(session, new ManagementPath("MicrosoftDNS_Zone"), null);
ManagementBaseObject inParams = zoneObj.GetMethodParameters("CreateZone");
inParams["ZoneName"] = "thedomain.com";
inParams["ZoneType"] = 0;
ManagementBaseObject outParams = zoneObj.InvokeMethod("CreateZone", inParams, null);
This creates the zone, but creates it with the type "Standard Primary". I need it to create with the type "Active Directory - Integrated Primary". From all my research, the zone type of "0" should do this. Can anyone tell me why it won't create the zone as an active directory zone?

I figured it out. Anyone else with the same issue, you have to add the DsIntegrated parameter to tell it to use Active Directory. Here is the final code:
ManagementClass zoneObj = new ManagementClass(session, new ManagementPath("MicrosoftDNS_Zone"), null);
ManagementBaseObject inParams = zoneObj.GetMethodParameters("CreateZone");
inParams["ZoneName"] = "thedomain.com";
inParams["ZoneType"] = 0;
inParams["DsIntegrated"] = true; //--- this is what needed to be added
ManagementBaseObject outParams = zoneObj.InvokeMethod("CreateZone", inParams, null);
DsIntegrated
Indicates whether zone data is stored in the Active Directory or in files. If TRUE, the data is stored in the Active Directory; if FALSE, the data is stored in files.

Related

Creating a shared folder programmatically c#

I am trying to create the shared folder in computer management shares with the following code
ManagementClass managementClass = new ManagementClass("Win32_Share");
ManagementBaseObject inParams = managementClass.GetMethodParameters("Create");
ManagementBaseObject outParams;
inParams["Description"] = Description;
inParams["Name"] = ShareName;
inParams["Path"] = FolderPath;
inParams["Type"] = 0x0; // Disk Drive
outParams = managementClass.InvokeMethod("Create", inParams, null);
var res = (uint)(outParams.Properties["ReturnValue"].Value);
res always returns 2.
Can anyone be of help in this regard?
What does it 2 mean and what are all the other output parameters?
Based on Create method of Win32_Share documentation , possible return values are :
Success (0)
Access denied (2)
Unknown failure (8)
Invalid name (9)
Invalid level (10)
Invalid parameter (21)
Duplicate share (22)
Redirected path (23)
Unknown device or directory (24)
Net name not found (25)
Other (26–4294967295)

Create VM with WMI in c#

I am trying to create a VM in Hyper-V with WMI.
ManagementClass virtualSystemManagementService =
new ManagementClass(#"root\virtualization\v2:Msvm_VirtualSystemManagementService");
ManagementBaseObject inParams =
virtualSystemManagementService
.GetMethodParameters("DefineSystem");
// Add the input parameters.
ManagementClass virtualSystemSettingData =
new ManagementClass(#"root\virtualization\v2:Msvm_VirtualSystemSettingData")
{
["ElementName"] = "Test"
};
inParams["SystemSettings"] =
virtualSystemSettingData.GetText(TextFormat.CimDtd20);
// Execute the method and obtain the return values.
ManagementBaseObject outParams =
virtualSystemManagementService
.InvokeMethod("DefineSystem", inParams, null);
The call to InvokeMethod throws an System.Management.MangementException - "Invalid method Parameter(s).
I am basing this code on https://blogs.msdn.microsoft.com/virtual_pc_guy/2013/06/20/creating-a-virtual-machine-with-wmi-v2/
I do realize that this is really easy with powershell, but I am trying to understand how the WMI side of things works.
Basic workflow For Virtual Machine Creation using WMI with C#:
You missed creating an instance of VirtualSystemSettingData and getting an instance of VirtualSystemManagment Service.
The exception System.Management.MangementException - "Invalid method Parameter(s) is thrown when you call invoke method on a class not an object!
Create VirtualSystemSettingData class
Add Properties
Create new VirtualSystemSettingData instance
Convert to text
Pass to params
Create VirtualSystemManagementService class
Get existing VirtualSystemManagementService instance
Invoke Method
Example:
ManagementClass virtualSystemManagementServiceClass =
new ManagementClass(#"root\virtualization\v2:Msvm_VirtualSystemManagementService");
ManagementBaseObject inParams =
virtualSystemManagementServiceClass
.GetMethodParameters("DefineSystem");
// Add the input parameters.
ManagementClass virtualSystemSettingDataClass =
new ManagementClass(#"root\virtualization\v2:Msvm_VirtualSystemSettingData")
{
["ElementName"] = "Test"
};
// Create Instance of VirtualSystemSettingData
ManagementObject virtualSystemSettingData = virtualSystemSettingDataClass.CreateInstance();
inParams["SystemSettings"] =
virtualSystemSettingData.GetText(TextFormat.CimDtd20);
// Get Instance of VirtualSystemManagmentService
ManagementObject virtualSystemManagementService = null;
foreach (ManagementObject instance in virtualSystemManagementServiceClass.GetInstances())
{
virtualSystemManagementService = instance;
break;
}
// Execute the method and obtain the return values.
ManagementBaseObject outParams = virtualSystemManagementService.InvokeMethod("DefineSystem", inParams, null);
You need to create an instance of msvm_VirtualSystemSettingData.
ManagementObject newInstance = new ManagementClass(scope, new ManagementPath("Msvm_VirtualSystemSettingData"), null).CreateInstance();
newInstance["ElementName"] = vmName;
inParameters["SystemSettings"] = newInstance.GetText(TextFormat.CimDtd20);

Sharing Folder API

I have C# WinForm application that needs to set sharing permission to some folder, and specify what users have access read/write/delete.
I was wondering if there is any api or way to call something similar to when you right click on folder select Properties/Sharing/Advanced Sharing and window opens.
If you know of anyway calling this window from c# I would appreciate if you share your knowledge.
I want to call this window.
You can do it through Win32 API:
private static void QshareFolder(string FolderPath, string ShareName, string Description)
{
try
{
// Create a ManagementClass object
ManagementClass managementClass = new ManagementClass("Win32_Share");
// Create ManagementBaseObjects for in and out parameters
ManagementBaseObject inParams = managementClass.GetMethodParameters("Create");
ManagementBaseObject outParams;
// Set the input parameters
inParams["Description"] = Description;
inParams["Name"] = ShareName;
inParams["Path"] = FolderPath;
inParams["Type"] = 0x0; // Disk Drive
// Invoke the method on the ManagementClass object
outParams = managementClass.InvokeMethod("Create", inParams, null);
if ((uint)(outParams.Properties["ReturnValue"].Value) != 0)
{
throw new Exception("Unable to share directory.");
}
}
catch (Exception ex)
{
//MessageBox.Show(ex.Message, "error!");
}
}
Usage:
QshareFolder("c:\TestShare", "Test Share", "This is a Test Share");
Source: http://www.codeproject.com/Articles/18624/How-to-Share-Windows-Folders-Using-C
There is no any standart API for this task.
Try this project to implement what you need How to Share Windows Folders Using C# (and here there is another example https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/de213b61-dc7e-4f33-acdb-893aa96837fa/c-set-directory-sharing-permission-full-control-for-everyone-programmatically-in-windows-7-or?forum=windowssdk)
Notice that your application will need to be running with Administrative access in order to share a folder.

Enabling filestream with WMI and C#

I have need to enable FILESTREAM on a SQL Server through a program. According to documentation I have found, this can be done through WMI with the following code:
set fsInstance = GetObject("WINMGMTS:\\" & MachineName & "\root\Microsoft\SqlServer\ComputerManagement10:FilestreamSettings='" & InstanceName & "'")
Set method = fsInstance.Methods_("EnableFilestream")
Set inParam = method.inParameters.SpawnInstance_()
inParam.AccessLevel = TargetLevel
inParam.ShareName = ShareName
Set outParam = fsInstance.ExecMethod_("EnableFilestream", inParam)
Converting this to C#, I get the following:
ManagementClass mc = new ManagementClass(new ManagementScope(#"\\.\root\Microsoft\SqlServer\ComputerManagement10"),
new ManagementPath("FilestreamSettings"),
new ObjectGetOptions(new ManagementNamedValueCollection() {
{"InstanceName", "MSSQLSERVER"}
}));
ManagementBaseObject inParams = mc.GetMethodParameters("EnableFilestream");
inParams["AccessLevel"] = 1;
inParams["ShareName"] = "ALLIANCE";
mc.InvokeMethod("EnableFilestream", inParams, null);
Whenever I try this, though, it throws an exception on InvokeMethod. The message is "Invalid method parameter(s)". I have attempted to remove the two lines where I set AccessLevel and ShareName and run it that way, but get the same exception. What am I doing wrong here?

How to add a DNS alias programmatically?

I want to create an alias record in Microsoft's DNS server to point AliasA to ComputerA. How can I do this programmatically?
I used WMI to do this, found an example on the web, and this is what it looked like.
private ManagementScope _session = null;
public ManagementPath CreateCNameRecord(string DnsServerName, string ContainerName, string OwnerName, string PrimaryName)
{
_session = new ManagementScope("\\\\" + DnsServerName+ "\\root\\MicrosoftDNS", con);
_session.Connect();
ManagementClass zoneObj = new ManagementClass(_session, new ManagementPath("MicrosoftDNS_CNAMEType"), null);
ManagementBaseObject inParams = zoneObj.GetMethodParameters("CreateInstanceFromPropertyData");
inParams["DnsServerName"] = ((System.String)(DnsServerName));
inParams["ContainerName"] = ((System.String)(ContainerName));
inParams["OwnerName"] = ((System.String)(OwnerName));
inParams["PrimaryName"] = ((System.String)(PrimaryName));
ManagementBaseObject outParams = zoneObj.InvokeMethod("CreateInstanceFromPropertyData", inParams, null);
if ((outParams.Properties["RR"] != null))
{
return new ManagementPath(outParams["RR"].ToString());
}
return null;
}
I don't think .NET has anything to provide access to these (all I can find in a bit of quick searching is references to proprietary libraries, controls, etc.), so you'll probably have to use the Win32 API via P/Invoke (though another possibility would be to do the job via WMI).
You'd start with DnsAcquireContextHandle, then (probably) DnsQuery to get a current record set, modify its contents to add your new alias, DnsReplaceRecordSet to have the DNS server use the new set of records, and finally DnsReleaseContextHandle to shut things down.
Of course, you'll need the right permissions on the server or none of this will work at all.

Categories