Question [BUG] WMI et la méthode Put()
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
-
- Messages : 6311
- Remerciements reçus 68
Le code suivant, une adaptation d'un fichier MOF , utilise la propriété __path d'une nouvelle instance WMI
[code:1]$ClassDataProv= [wmiclass]\"root\TestVues:__Win32Provider\"
$DataProv= $ClassDataProv.CreateInstance()
$DataProv.Name = \"MS_VIEW_INSTANCE_PROVIDER\";
$DataProv.ClsId = \"{AA70DDF4-E11C-11D1-ABB0-00C04FD9159E}\"
$DataProv.ImpersonationLevel = 1
$DataProv.PerUserInitialization = $True
$DataProv.HostingModel = \"NetworkServiceHost\"
$DataProv.put()[/code:1]
Sous PowerShell V1 l’accés aux propriétés système de la nouvelle instance WMI nécessite de forcer l’adaptation de l'objet WMI, encapsulé dans un objet dotnet.
Ceci est corrigé avec la version de Powershell v2 livrée avec la RC1 de Windows Seven.
Sous PS v1, on peut, d'après mes tests, forcer l'adaptation ainsi
[code:1]
$DataProv.Put()
$DataProv|SELECT __* > $NULL
[/code:1]
Sans cette instruction, sous PS v1 et PS v2 CTP 3, l’accès en lecture de la propriété __path renvoie une valeur nulle.
Ce qui pose problème pour la séquence de code suivante :
[code:1]$ClassProvReg= [wmiclass]\"root\TestVues:__InstanceProviderRegistration\"
$ProvReg= $ClassProvReg.CreateInstance()
#C’est une référence, on pointe sur le chemin de l’instance WMI
# et pas sur la variable PowerShell
$ProvReg.Provider =$DataProv.__Path
$ProvReg.SupportsPut = $True
$ProvReg.SupportsGet = $True
$ProvReg.SupportsDelete = $True
$ProvReg.SupportsEnumeration =$True
$ProvReg.QuerySupportLevels =@(\"WQL:UnarySelect\"«»)
$ProvReg.put()
[/code:1]
Dans ce cas le contenu de la variable $DataProv.__Path sera à égale $null, ce qui provoquera une erreur lors de l'appel à $ProvReg.Put().
On peut corriger ceci, pour la propriété __Path, en utilisant la valeur de retour de l'appel à la méthode Put() :
[code:1]...
$Result=$DataProv.put()
...
$ProvReg.Provider =$Result.Path
...[/code:1]
C'est sûr que ce code n'est pas d'un usage courant, mais pour ceux utilisant des fonctionnalités avancées de WMI, autre que la simple lecture d'instance, cette information pourra leur faire gagner du temps.
ps
Je posterais le code complet une fois celui-ci testé
[code:1]
$ClassNS = [wmiclass]\"root:__Namespace\"
$NS = $ClassNS.CreateInstance()
$NS.Name = \"TestVues\"
$NS.put()
$ClassDataProv= [wmiclass]\"root\TestVues:__Win32Provider\"
$DataProv= $ClassDataProv.CreateInstance()
$DataProv.Name = \"MS_VIEW_INSTANCE_PROVIDER\";
$DataProv.ClsId = \"{AA70DDF4-E11C-11D1-ABB0-00C04FD9159E}\"
$DataProv.ImpersonationLevel = 1
$DataProv.PerUserInitialization = $True
$DataProv.HostingModel = \"NetworkServiceHost\"
$Result=$DataProv.put()
$ClassProvReg= [wmiclass]\"root\TestVues:__InstanceProviderRegistration\"
$ProvReg= $ClassProvReg.CreateInstance()
#C’est une référence, on pointe sur le chemin de l’instance WMI
# et pas sur la variable PowerShell
$ProvReg.Provider =$Result.Path
$ProvReg.SupportsPut = $True
$ProvReg.SupportsGet = $True
$ProvReg.SupportsDelete = $True
$ProvReg.SupportsEnumeration =$True
$ProvReg.QuerySupportLevels =@(\"WQL:UnarySelect\"«»)
$ProvReg.put()
$ClassMethodProvReg=[wmiclass]\"root\TestVues:__MethodProviderRegistration\"
$MethodProvReg = $ClassMethodProvReg.CreateInstance()
$MethodProvReg.Provider =$Result.Path
$MethodProvReg.put()
#TODO création d'une 'jointure WMI'
[/code:1]
Quelqueq infos sur la création d'instance WMI.
Savoir si une classe peut être créée, supprimée, modifiée :
[code:1]([wmiclass]\"Win32_Environment\"«»).psbase.Qualifiers|? {
$_.name -match \"^Supports\"}| Select name[/code:1]
Pour connaître le mode de création d’une instance d’une classe :Name
----
SupportsCreate
SupportsDelete
SupportsUpdate
[code:1]\"Win32_Process\",\"Win32_Environment\"|`
Foreach {
([wmiclass]\"$_\"«»).psbase.Qualifiers| `
Where {$_.name -match \"By$\"}|`
Select Name,value
}[/code:1]
<br><br>Message édité par: Laurent Dardenne, à: 1/06/09 11:57Name Value
----
CreateBy Create # Win32_Process
DeleteBy DeleteInstance
CreateBy PutInstance # Win32_Environment
DeleteBy DeleteInstance
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
-
- Messages : 6311
- Remerciements reçus 68
Le fichier texte de déclaration de la classe de jointure :
Puis on compile la classe dans l'espace de nom porté par le fichier précédent, \root\TestVues#pragma namespace(\"\\\\.\\root\\TestVues\")
[
JoinOn(\"Win32_DiskPartition.DiskIndex = Win32_DiskDrive.Index\"),
ViewSources{
\"SELECT DiskIndex, Index, DeviceID FROM Win32_DiskPartition\" ,
\"SELECT Index, Caption, Model FROM Win32_DiskDrive\"},
ViewSpaces{
\"\\\\.\\root\\cimv2\",
\"\\\\.\\root\\cimv2\"},
dynamic: ToInstance,
provider(\"MS_VIEW_INSTANCE_PROVIDER\")
]
class JoinedPartitionDisk
{
[PropertySources{\"DiskIndex\", \"Index\"}] UInt32 ID;
[PropertySources{\"\", \"Caption\"}] String Caption;
[PropertySources{\"DeviceID\", \"\"},Key] String DeviceId;
[PropertySources{\"\", \"Model\"}] String Model;
};
[code:1]
mofcomp JoinedPartitionDisk.Mof
[/code:1]
Ensuite on peut récupérer les instances :
[code:1]gwmi -namespace \"root\TestVues\" -class \"JoinedPartitionDisk\"[/code:1]
L'ajout d'un cmdlet Join-Object ou Merge-object aurait été appréciable, bien qu'ici la création des instances soit prise en charge par WMI.<br><br>Message édité par: Laurent Dardenne, à: 3/06/09 14:27
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Vous êtes ici :
-
Accueil
-
forum
-
PowerShell
-
Contributions à la communauté
- [BUG] WMI et la méthode Put()