WMI : MSVM_Imagemanagmentservice mount method does not assign drive letter - wmi

I m trying to mount a vhd on windows 2012 hyperV core datacenter edition. For mounting the vhd I m using the MSVM_Imagemanagementservice class and mount method inside that. The disk is mounted but the problem is no drive letter is getting assigned. I have tried it on other 2012 datacenter edition and 2012 core as well it works fine. i.e after mount the drive letter gets assigned.
Any thoughts on this will help.

You can query for the drive letters list and then assign the drive letter as per your requirement. Given below is the function to get the drive letters list.
Function GetDriveLetterList(path)
'Where path is path of VHD
Dim mountedImage, diskDevice, diskPartition, diskPartitions, logicalPartition, timeout, query
Dim logicalPartitionList
timeout = 0
driveLetterList = ""
path = Replace(path,"\","\\")
Set wmiServiceCIM = GetObject("winmgmts:\\.\root\cimv2")
Do
WScript.Sleep(3000)
timeout = timeout + 3
Set mountedImage = (wmiService.ExecQuery("SELECT * FROM Msvm_MountedStorageImage WHERE Name='" & path & "'")).ItemIndex(0)
query = "SELECT * From Win32_DiskDrive WHERE Model='Msft Virtual Disk SCSI Disk Device' and SCSITargetId='" & mountedImage.TargetId & "' and SCSILogicalUnit='" & mountedImage.Lun & "' and SCSIPort='" & mountedImage.PortNumber & "'"
Set diskDevice = wmiServiceCIM.ExecQuery(query).ItemIndex(0)
query = "ASSOCIATORS OF {" & diskDevice.Path_.Path & "} where AssocClass=Win32_DiskDriveToDiskPartition"
Set diskPartitions = wmiServiceCIM.ExecQuery(query)
For Each diskPartition In diskPartitions
query = "ASSOCIATORS OF {" & diskPartition.Path_.Path & "} WHERE AssocClass=Win32_LogicalDiskToPartition"
Set logicalPartitionList = wmiServiceCIM.ExecQuery(query)
If logicalPartitionList.count > 0 Then
Set logicalPartition = logicalPartitionList.ItemIndex(0)
'WScript.Echo logicalPartition.DeviceID
driveLetterList = driveLetterList + logicalPartition.DeviceID
End If
Next
End Function
If you want to check for systems drive . Then you can do this ...
folderPath = driveLetter + ":\Windows\System32"
Set fileSys = CreateObject("Scripting.FileSystemObject")
If filesys.FolderExists(folderPath) Then
//doStuff
End If

Related

How do i get SerialNumber of BaseBoard with WMI?

A nice example is there to use WMI in Powerbuilder that terminates a running process.
The same technique can be used to get SerialNumber of BaseBoard. I need to extend the same code to handle return values of the WQL query.
The WQL query i want to execute is:
SELECT Product, SerialNumber FROM Win32_BaseBoard
I can execute the query above but dont know how to save the SerialNumber in a variable after the ExecuteStatement() function is called.
Please take a look at the link for complete PowerBuilder code.
How to terminate a process if it has specific folder name in its path?
Following is a portion of a sample code taken from the link above to show the function.
wsh = CREATE OleObject
wsh.ConnectToNewObject("MSScriptControl.ScriptControl")
wsh.Language = "VBScript"
wsh.AddCode(TheCode)
TRY
wsh.ExecuteStatement(FunctionName)
CATCH (RunTimeError Re01)
MessageBox("Query Error", "Following code has some problems.~r~n~r~n" + TheCode, StopSign!)
END TRY
wsh.DisconnectObject()
DESTROY wsh
The important function call
wsh.ExecuteStatement(FunctionName)
What to do after that function call to set my PowerBuilder local variables with the returned SerialNumber of BaseBoard?
OLEObject ole_wsh
Any la_baseboard[]
string ls_message
ole_wsh = CREATE OLEObject
ole_wsh.ConnectToNewObject("MSScriptControl.ScriptControl")
ole_wsh.Language = "vbscript"
ole_wsh.AddCode('Function rtnBaseBoard()~r~n' &
+ 'DIM objBaseBoard(2)~r~n' &
+ 'strComputer = "."~r~n' &
+ 'Set objWMIService =' &
+ ' GetObject("winmgmts:\\" & strComputer & "\root\cimv2")~r~n' &
+ 'Set colItems =' &
+ ' objWMIService.ExecQuery("SELECT Product, SerialNumber FROM Win32_BaseBoard")~r~n' &
+ 'For Each objItem in colItems~r~n' &
+ 'objBaseBoard(0) = objItem.Product~r~n' &
+ 'objBaseBoard(1) = objItem.SerialNumber~r~n' &
+ 'Next~r~n' &
+ 'rtnBaseBoard = objBaseBoard~r~n' &
+ 'End Function')
la_baseboard[] = ole_wsh.Eval("rtnBaseBoard")
ole_wsh.DisconnectObject()
DESTROY ole_wsh
ls_message = "Product: " + string(la_baseboard[1]) + "~r~n" + &
+ "SerialNumber: " + string(la_baseboard[2]) + "~r~n"
MessageBox("Win32 BaseBoard",ls_message)
See more examples using WMI from Powerbuilder

having an issue with an if then statement using vbYesNo

I am trying to create a script that will ask the user if they want to set a network printer as their default. My problem is that no matter what they select (yes or no) it set it up as the default and it always echo's my the echo statement under else. Can someone tell me what I am doing wrong?
` ' Printers.vbs - Windows Logon Script.
printername = "DCPTTEAM462W"
server = "DCDEPLOY03"
Dim objectNetwork, printer
printer = "\\DCPRINT03\DCPTTEAM462W"
Msgbox printername & " will now install on your computer.",0, "Add printer" & printername
intRespnseY = Msgbox("Would you like " & printername & " to be set as your default printer", vbYesNo, "Set as Default")
If intResponseY = vbNo Then
Set objNetwork = CreateObject("WScript.Network")
objNetwork.AddWindowsPrinterConnection printer
WScript.Echo "DCPTTEAM462W was added as a printer."
Else
Set objNetwork = CreateObject("WScript.Network")
objNetwork.AddWindowsPrinterConnection printer
objNetwork.SetDefaultPrinter printer
WScript.Echo "DCPTTEAM462W has been set as your default printer."
End If
`
You have a typo:
intRespnseY = Msgbox(....
Should be
intResponseY = Msgbox(....
Use
Option Explicit
to avoid blunders like:
intRespnseY = Msgbox("...")
If intResponseY = vbNo Then
(mark the missing "o")

c# NetworkInterface.GetAllNetworkInterfaces vs WMI Win32_NetworkAdapter

I get a InterfaceIndex with GetBestInterface (iphlpapi.dll).
The goal : read other interface properties.
This WMI query is slow :
SELECT MACAddress,Name,GUID,NetConnectionID FROM Win32_NetworkAdapter WHERE InterfaceIndex=
In C# there is, faster,
NetworkInterface.GetAllNetworkInterfaces()
but each NetworkInterface hasn't the property InterfaceIndex ( sic ! ).
I don't know how to optimize this :
EnumerationOptions wmi_options = new EnumerationOptions();
wmi_options.Rewindable = false;
wmi_options.ReturnImmediately = true;
string wql = "SELECT MACAddress,Name,GUID,NetConnectionID FROM Win32_NetworkAdapter WHERE InterfaceIndex=" + iface;
ManagementObjectCollection recordset = new ManagementObjectSearcher(#"root\cimv2", wql, wmi_options).Get();
foreach (ManagementObject mo in recordset)
The options don't seem to help.
Can I split the operations and cache any step ?
Or another path : avoid WMI and lookup the interface ( with InterfaceIndex ) from the registry ?
HKLM\SYSTEM\CurrentControlSet\Services\tcpip\Parameters\Interfaces
HKLM\SYSTEM\CurrentControlSet\Control\Network{4D36E972-E325-11CE-BFC1-08002BE10318}
i dont know if this is actually faster but have you tried powershell?
string IfIndex = "15";
string psscript = "get-netadapter | Where-Object interfaceindex -eq " + IfIndex;
PowerShell powershell = PowerShell.Create();
powershell.Runspace = RunspaceFactory.CreateRunspace();
powershell.Runspace.Open();
powershell.AddScript(psscript);
foreach (PSObject result in powershell.Invoke())
{
Console.WriteLine("Name: {0} " + "Status: {1}",result.Members["Name"].Value, result.Members["status"].Value);
}
Console.Read();
run this from your application, using System.Management.Automation &
System.Management.Automation.Runspaces;
i haven't tested the code yet, this is the top of my head.

WMI USB Enable and Disable

Hi I am using WMI to change the remote registry value for USBSTOR. I want to change the value of start attribute to 4 or 3 for enabling and disabling.
But the datatype for Start attribute in registry is DWORD, if i can the datatype to size it does not work .
I need to keep the Datatype to DWORD. Can someone please tell me how to setDWORDValue using WMI, following is the piece of code that i tried, it worked succesfully but still the value of start field is unchanged in registry.
const uint HKEY_LOCAL_MACHINE = 0x80000002;
ManagementBaseObject methodParams = registryTask.GetMethodParameters(typeOfValue);
methodParams["hDefKey"] = HKEY_LOCAL_MACHINE;// BaseKey;
methodParams["sSubKeyName"] = #"SYSTEM\\CurrentControlSet\\Servic\\USBSTOR";
methodParams["sValueName"] = "Start";
try
{
methodParams["sValue"] = "3";
}
catch
{
methodParams["uValue"] = (UInt32)Convert.ToInt32("3");
}
ManagementBaseObject exitValue = registryTask.InvokeMethod(typeOfValue, methodParams, null);
Simple solution using python.
import wmi
import win32api,_winreg
c = wmi.WMI()
# To get the binary value of particular subkey
# Please note that 0x80000002 represents HKEY_LOCAL_MACHINE
ReturnValue, uValue = c.StdRegProv.GetBinaryValue(0x80000002,"AFD","SYSTEM\CurrentControlSet\Services")
# To get the list of all the subkeys available in particular key
ret, subKeys = c.StdRegProv.EnumKey (0x80000002, "SYSTEM\CurrentControlSet\Services")
print ret
for key in subKeys:
print key
ReturnValue=c.StdRegProv.SetDWORDValue(0x80000002,"Type","SYSTEM\CurrentControlSet\Services\USBSTOR",0x4)
#HKEY_CLASSES_ROOT (2147483648 (0x80000000))
#HKEY_CURRENT_USER (2147483649 (0x80000001))
#HKEY_LOCAL_MACHINE (2147483650 (0x80000002))
#HKEY_USERS (2147483651 (0x80000003))
#HKEY_CURRENT_CONFIG (2147483653 (0x80000005))
#HKEY_DYN_DATA (2147483654 (0x80000006))
Yes it can be done. Here's the code, referencing this Microsoft link and this one. Replace 3389 with the new value you want to use, and change the key as needed:
const HKEY_LOCAL_MACHINE = &H80000002
strComputer = "."
'Set StdOut = WScript.StdOut
Set oReg=GetObject( _
"winmgmts:{impersonationLevel=impersonate}!\\" &_
strComputer & "\root\default:StdRegProv")
strKeyPath = "SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp"
strValueName = "PortNumber"
' Display old value
oReg.GetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,dwValue
WScript.Echo "Old RDP value=" & dwValue
' Set new value
dwValue= 3389
oReg.SetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,dwValue
If Err = 0 Then
oReg.GetDWORDValue _
HKEY_LOCAL_MACHINE,strKeyPath,strValueName,dwValue
WScript.Echo "New RDP Value =" & dwValue
Else
WScript.Echo "Error in creating key" & _
" and DWORD value = " & Err.Number
End If

use wmi to get newest Windows log events

I want to use WMI to monitor the Windows event log and get newest log events every 15 minute. Although I can use WQL to do the query, it does not have the keywords such as order by. Any ideas how to work around this problem?
you can use a dataset. Below is done using vbscript, and only on the fields ComputerName,EventCode and Message. Add the other fields as desired
Const adVarChar = 200
Const MaxCharacters = 1024
Const adFldIsNullable = 32
Set DataList = CreateObject("ADOR.Recordset")
DataList.Fields.Append "ComputerName", adVarChar, MaxCharacters,adFldIsNullable
DataList.Fields.Append "EventCode", adVarChar, MaxCharacters,adFldIsNullable
DataList.Fields.Append "Message",adVarChar,MaxCharacters,adFldIsNullable
DataList.Open
strComputer = "."
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colLoggedEvents = objWMIService.ExecQuery("Select * from Win32_NTLogEvent Where Logfile = 'Application'")
For Each evt in colLoggedEvents
DataList.AddNew
DataList("ComputerName") = evt.ComputerName
DataList("EventCode") = evt.EventCode
DataList("Message") = evt.Message
DataList.Update
Next
'sort by eventcode
DataList..Sort = "EventCode DESC"
DataList.MoveFirst
Do Until DataList.EOF
Wscript.Echo DataList.Fields.Item("ComputerName") & vbTab & DataList.Fields.Item("EventCode") & vbTab & DataList.Fields.Item("Message")
DataList.MoveNext
Loop