Posts Tagged ‘WMI’
Creating Hosts with Powershell
[UPDATE]: The issue I had has now been solved. Please refer to the text below for the original issues as well as the solution
Context: Basically I was trying to write the powershell equivalent of the MSDN Article : Creating a Host using WMI
For the C# version of the sample here is the powershell equivalent
$putOptions = new-Object System.Management.PutOptions
$putOptions.Type = [System.Management.PutType]::CreateOnly;
[System.Management.ManagementClass]$objHostSettingClass = New-Object
System.Management.ManagementClass(“root\MicrosoftBizTalkServer”,”MSBTS_HostSetting”,$null)
[System.Management.ManagementObject]$objHostSetting = New-Object
System.Management.ManagementObject
$objHostSetting = $objHostSettingClass.CreateInstance()
$objHostSetting[“Name”] = $hostName
$objHostSetting[“HostType”] = $hostType
$objHostSetting[“NTGroupName”] = $NTGroupName
$objHostSetting[“AuthTrusted”] =$authTrusted
[System.Management.ManagementObject]($objHostSetting).Put(([System.Management.PutOptions]$putOptions));
This gives me the error
Exception calling “Put” with “1” argument(s): “You cannot call a method on a
null-valued expression.”
If i try the VBscript version (PS equivalent) as shown below
$objLocator = New-Object -ComObject “WbemScripting.SWbemLocator”
$objService = $objLocator.ConnectServer(“.”,”root/MicrosoftBizTalkServer”)
$objHostSetting = $objService.Get(“MSBTS_HostSetting”)
$objHS = $objHostSetting.SpawnInstance_
$objHS.HostName = $hostName
$objHS.HostType = $hostType
$objHS.NTGroupName = $NTGroupName
$objHS.AuthTrusted = $authTrusted
$objHS.Put(2)
Then i get an error saying : the property is read only (name, hosttype etc)
changing the assignment to the following
$objHS.Properties_.Item(“Name”).value = $hostName
does not work either, saying
You cannot call a method on a null-valued expression.
SOLUTION
In the original post, I had said that I was going to try to solve the problem through Reflection and indeed that was the only way i could get it to work.
In the code (for the C#/PS equivalent) shown above , it appears that the line [$objHostSetting.Put($options)] is the offender. Although $objHostSetting gets initialised correctly and all properties get set, the Put method cannot be called on it. At the time of invocation it seems that PS thinks its null.
It was a very painful process (for a PS newbie) and the reflection equivalent isn’t an exact translation of the C# either. The Invoke() method requires an object[] in C# but in PS you just pass the actual object and it will work
PS Script
function bts-host-create([string]$hostName, [int]$hostType, [string]$NTGroupName, [bool]$authTrusted)
{
$putOptions = new-Object System.Management.PutOptions
$putOptions.Type = [System.Management.PutType]::CreateOnly;
[System.Management.ManagementClass]$objHostSettingClass = New-Object System.Management.ManagementClass(“root\MicrosoftBizTalkServer”,”MSBTS_HostSetting”,$null)
[System.Management.ManagementObject]$objHostSetting = New-Object System.Management.ManagementObject
$objHostSetting = $objHostSettingClass.CreateInstance()
$objHostSetting[“Name”] = $hostName
$objHostSetting[“HostType”] = $hostType
$objHostSetting[“NTGroupName”] = $NTGroupName
$objHostSetting[“AuthTrusted”] =$authTrusted
[Type[]] $targetTypes = New-Object System.Type[] 1
$targetTypes[0] = $putOptions.GetType()
$sysMgmtAssemblyName = “System.Management”
$sysMgmtAssembly = [System.Reflection.Assembly]::LoadWithPartialName($sysMgmtAssemblyName)
$objHostSettingType = $sysMgmtAssembly.GetType(“System.Management.ManagementObject”)
[Reflection.MethodInfo] $methodInfo = $objHostSettingType.GetMethod(“Put”,$targetTypes)
$methodInfo.Invoke($objHostSetting,$putOptions)
Write-Host “Successfully created host named: $hostName”
}
Here’s the C# code
public static void CreateHostThroughReflection(string HostName, int HostType, string NTGroupName, bool AuthTrusted)
{
try
{
PutOptions options = new PutOptions();
options.Type = PutType.CreateOnly;
//create a ManagementClass object and spawn a ManagementObject instance
ManagementClass objHostSettingClass = new ManagementClass(“root\\MicrosoftBizTalkServer”, “MSBTS_HostSetting”, null);
ManagementObject objHostSetting = objHostSettingClass.CreateInstance();
//set the properties for the Managementobject
objHostSetting[“Name”] = HostName;
objHostSetting[“HostType”] = HostType;
objHostSetting[“NTGroupName”] = NTGroupName;
objHostSetting[“AuthTrusted”] = AuthTrusted;
Type[] targetTypes = new Type[1];
targetTypes[0]= typeof(PutOptions);
object[] parameters = new object[1];
parameters[0] = options;
Type objType = objHostSetting.GetType();
MethodInfo mi = objType.GetMethod(“Put”,targetTypes);
mi.Invoke(objHostSetting, parameters);
//create the Managementobject
//objHostSetting.Put(options);
System.Console.WriteLine(“Host – ” + HostName + ” – has been created successfully”);
}
catch (ManagementException mex)
{
Console.WriteLine(“Management Exception ” + mex.Message);
}
catch (Exception excep)
{
System.Console.WriteLine(“CreateHost – ” + HostName + ” – failed: ” + excep.Message);
}
}
Notice that the “Invoke” is different in the PS and the C#. Also notice how convoluted the PS is when trying to do a simple object.GetType() , but i guess PS wasnt meant for this sort of thing anyway, so we cant complain.
Hope this helps someone. Do let me know if it does. Use the code for whatever you want but i dont provide support 🙂