Connexion à WMI à distance en C#
Comme avec d’autres langages tels que PowerShell, VBScript ou C++, vous pouvez utiliser le C# pour effectuer un monitoring à distance du matériel et des logiciels sur des ordinateurs distants. Les connexions à distance pour le code managé s’effectuent via l’espace de noms Microsoft.Management.Infrastructure. (Les versions antérieures de WMI utilisaient l’espace de noms System.Management, qui est inclus ici par souci d’exhaustivité.)
Notes
System.Management était l’espace de noms .NET d’origine utilisé pour accéder à WMI. Toutefois, les API de cet espace de noms sont généralement plus lentes et ne se mettent pas à l’échelle aussi bien que leurs homologues Microsoft.Management.Infrastructure plus modernes.
La connexion à distance à l’aide de classes de l’espace de noms Microsoft.Management.Infrastructure utilise DCOM en tant que mécanisme distant sous-jacent. Les connexions distantes WMI doivent être conformes aux critères de sécurité DCOM en matière d'emprunt d'identité et d'authentification. Par défaut, une étendue est liée à l’ordinateur local et à l’espace de noms système « Root\CIMv2 ». Toutefois, vous pouvez changer l’ordinateur, le domaine et l’espace de noms WMI auxquels vous accédez. Vous pouvez également définir l’autorité, l’emprunt d’identité, les informations d’identification et d’autres options de connexion.
Pour se connecter à WMI à distance en C# (Microsoft.Management.Infrastructure)
Créez une session sur la machine distante en appelant CimSession.Create.
Si vous vous connectez à un ordinateur distant à l’aide des mêmes informations d’identification (domaine et nom d’utilisateur) que celles avec lesquelles vous êtes connecté, vous pouvez spécifier le nom de l’ordinateur dans l’appel à Create. Une fois l’objet CimSession retourné, vous pouvez effectuer votre requête WMI.
using Microsoft.Management.Infrastructure; ... string Namespace = @"root\cimv2"; string OSQuery = "SELECT * FROM Win32_OperatingSystem"; CimSession mySession = CimSession.Create("Computer_B"); IEnumerable<CimInstance> queryInstance = mySession.QueryInstances(Namespace, "WQL", OSQuery);
Pour plus d’informations sur la création de requêtes WMI avec l’API Microsoft.Management.Infrastructure en C#, consultez Récupération de données de classe ou d’instance WMI.
Si vous souhaitez définir différentes options pour votre connexion, par exemple des informations d’identification, des paramètres régionaux ou des niveaux d’emprunt d’identité distincts, vous devez utiliser un objet CimSessionOptions dans votre appel à CimSession.Create.
CimSessionOptions est une classe de base pour WSManSessionOptions et DComSessionOptions. Vous pouvez utiliser l’une ou l’autre de ces classes pour définir les options de vos sessions WS-Man et DCOM, respectivement. L’exemple de code suivant décrit l’utilisation d’un objet DComSessionOptions pour affecter la valeur Emprunter l’identité au niveau d’emprunt d’identité.
string computer = "Computer_B" DComSessionOptions DComOptions = new DComSessionOptions(); DComOptions.Impersonation = ImpersonationType.Impersonate; CimSession Session = CimSession.Create(computer, DComOptions);
Si vous souhaitez définir les informations d’identification de votre connexion, vous devez créer et ajouter un objet CimCredentials à CimSessionOptions.
L’exemple de code suivant décrit la création d’une classe WSManSessionOptions, son remplissage avec le CimSessionOptions approprié, puis son utilisation dans un appel à CimSession.Create.
string computer = “Computer_B”; string domain = “Domain1″; string username = “User1″; string plaintextpassword; //Retrieve password from the user. //For the complete code, see the sample at the bottom of this topic. CimCredential Credentials = new CimCredential(PasswordAuthenticationMechanism.Default, domain, username, securepassword); WSManSessionOptions SessionOptions = new WSManSessionOptions(); SessionOptions.AddDestinationCredentials(Credentials); CimSession Session = CimSession.Create(computer, SessionOptions);
Il est généralement recommandé de ne pas coder en dur un mot de passe dans vos applications. Comme l’indique l’exemple de code ci-dessus, essayez autant que possible d’interroger l’utilisateur pour obtenir le mot de passe, puis stockez-le de manière sécurisée.
WMI a été conçu pour contrôler le matériel et les logiciels sur des ordinateurs distants. Les connexions à distance pour WMI v1 s’effectuent via l’objet ManagementScope.
Pour se connecter à WMI à distance en C# (System.Management)
Créez un objet ManagementScope en utilisant le nom de l’ordinateur et le chemin WMI, puis connectez-vous à votre cible en appelant ManagementScope.Connect().
Si vous vous connectez à un ordinateur distant à l’aide des mêmes informations d’identification (domaine et nom d’utilisateur) que celles avec lesquelles vous êtes connecté, il vous suffit de spécifier le chemin WMI. Une fois connecté, vous pouvez effectuer votre requête WMI.
using System.Management; ... ManagementScope scope = new ManagementScope("\\\\Computer_B\\root\\cimv2"); scope.Connect(); ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_OperatingSystem"); ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
Pour plus d’informations sur la création de requêtes WMI avec l’API System.Management en C#, consultez Récupération de données de classe ou d’instance WMI.
Si vous vous connectez à un ordinateur distant dans un autre domaine ou à l’aide d’un autre nom d’utilisateur et d’un autre mot de passe, vous devez utiliser un objet ConnectionOptions dans l’appel à ManagementScope.
ConnectionOptions contient des propriétés permettant de décrire les options d’authentification, d’emprunt d’identité, de nom d’utilisateur, de mot de passe ainsi que d’autres options de connexion. L’exemple de code suivant décrit l’utilisation de ConnectionOptions pour affecter la valeur Emprunter l’identité au niveau d’emprunt d’identité.
ConnectionOptions options = new ConnectionOptions(); options.Impersonation = System.Management.ImpersonationLevel.Impersonate; ManagementScope scope = new ManagementScope("\\\\FullComputerName\\root\\cimv2", options); scope.Connect(); ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_OperatingSystem"); ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope,query);
En règle générale, il est recommandé d’affecter la valeur Emprunter l’identité à votre niveau d’emprunt d’identité, sauf indication contraire explicite. De plus, essayez d’éviter d’écrire votre nom et votre mot de passe dans le code C#. (Si possible, déterminez si vous pouvez demander à l’utilisateur de les fournir de manière dynamique au moment de l’exécution.)
Pour plus d’exemples de définition de différentes propriétés sur une connexion WMI distante, consultez la section Exemples de la page de référence ConnectionOptions.
Exemple Microsoft.Management.Infrastructure
L’exemple de code C# suivant, basé sur ce billet de blog sur TechNet, explique comment utiliser CimCredentials et WSManSessionOptions pour définir les informations d’identification d’une connexion à distance.
using System;
using System.Text;
using System.Threading;
using Microsoft.Management.Infrastructure;
using Microsoft.Management.Infrastructure.Options;
using System.Security;
namespace SMAPIQuery
{
class Program
{
static void Main(string[] args)
{
string computer = "Computer_B";
string domain = "DOMAIN";
string username = "AdminUserName";
string plaintextpassword;
Console.WriteLine("Enter password:");
plaintextpassword = Console.ReadLine();
SecureString securepassword = new SecureString();
foreach (char c in plaintextpassword)
{
securepassword.AppendChar(c);
}
// create Credentials
CimCredential Credentials = new CimCredential(PasswordAuthenticationMechanism.Default,
domain,
username,
securepassword);
// create SessionOptions using Credentials
WSManSessionOptions SessionOptions = new WSManSessionOptions();
SessionOptions.AddDestinationCredentials(Credentials);
// create Session using computer, SessionOptions
CimSession Session = CimSession.Create(computer, SessionOptions);
var allVolumes = Session.QueryInstances(@"root\cimv2", "WQL", "SELECT * FROM Win32_Volume");
var allPDisks = Session.QueryInstances(@"root\cimv2", "WQL", "SELECT * FROM Win32_DiskDrive");
// Loop through all volumes
foreach (CimInstance oneVolume in allVolumes)
{
// Show volume information
if (oneVolume.CimInstanceProperties["DriveLetter"].ToString()[0] > ' ' )
{
Console.WriteLine("Volume ‘{0}’ has {1} bytes total, {2} bytes available",
oneVolume.CimInstanceProperties["DriveLetter"],
oneVolume.CimInstanceProperties["Size"],
oneVolume.CimInstanceProperties["SizeRemaining"]);
}
}
// Loop through all physical disks
foreach (CimInstance onePDisk in allPDisks)
{
// Show physical disk information
Console.WriteLine("Disk {0} is model {1}, serial number {2}",
onePDisk.CimInstanceProperties["DeviceId"],
onePDisk.CimInstanceProperties["Model"].ToString().TrimEnd(),
onePDisk.CimInstanceProperties["SerialNumber"]);
}
Console.ReadLine();
}
}
}
Exemple System.Management
L’exemple de code C# suivant décrit une connexion à distance générale à l’aide des objets System.Management.
using System;
using System.Management;
public class RemoteConnect
{
public static void Main()
{
ConnectionOptions options = new ConnectionOptions();
options.Impersonation = System.Management.ImpersonationLevel.Impersonate;
ManagementScope scope = new ManagementScope("\\\\FullComputerName\\root\\cimv2", options);
scope.Connect();
//Query system for Operating System information
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_OperatingSystem");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope,query);
ManagementObjectCollection queryCollection = searcher.Get();
foreach ( ManagementObject m in queryCollection)
{
// Display the remote computer information
Console.WriteLine("Computer Name : {0}", m["csname"]);
Console.WriteLine("Windows Directory : {0}", m["WindowsDirectory"]);
Console.WriteLine("Operating System : {0}", m["Caption"]);
Console.WriteLine("Version : {0}", m["Version"]);
Console.WriteLine("Manufacturer : {0}", m["Manufacturer"]);
}
}
}
Rubriques connexes