Question [Resolu] [Module OnRemove] Delete Variable

Plus d'informations
il y a 13 ans 9 mois #7331 par Richard Lazaro
Bonjour (Re :P),

Je reviens vers vous pour un problème incompréhensible ...
Dans mon event OnRemove, je vois les variables, je peux afficher la valeur de chaque mais je peux pas les supprimer car PS me dit qu'il les trouve pas Oo

Voici comment ce présente mon Module

MyModule
|- MyModule.psd1 ( avec le ModuleToProcess='MyModule.psm1 )
|- MyModule.psm1 ( avec l'event OnRemove )

Quand j'importe le Module, les variables sont bien créées.

Voici mon event OnRemove :
[code:1]
$MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = {
Get-Variable ModuleFolder ; `
Get-Variable ModuleFolder ; `
Get-Variable MetadataFolder ; `
$ModuleFolder ; `
$MetadataDefaultHost ; `
$MetadataFolder ; `
Get-Variable ModuleFolder | Remove-Variable ; `
Get-Variable MetadataDefaultHost | Remove-Variable ; `
Get-Variable MetadataFolder | Remove-Variable ; `
Remove-Module HyperV }
[/code:1]

Et Voici le résultat du Prompt :
[code:1]
PS C:\> Import-Module .\Users\richardl.EXAKIS\Desktop\MyModule
PS C:\> Remove-Module MyModule

Name Value
----
ModuleFolder C:\Users\richardl.EXAKIS\Desktop\MyModule
ModuleFolder C:\Users\richardl.EXAKIS\Desktop\MyModule
MetadataFolder C:\MyModule\Metadata
C:\Users\richardl.EXAKIS\Desktop\MyModule
127.0.0.1
C:\MyModule\Metadata
Remove-Variable : Impossible de trouver une variable assortie du nom « ModuleFolder ».
Au niveau de C:\Users\richardl.EXAKIS\Desktop\MyModule\MyModule.psm1 : 36 Caractère : 46
+ Get-Variable ModuleFolder | Remove-Variable <<<< ; `
+ CategoryInfo : ObjectNotFound: (ModuleFolder:«»String) [Remove-Variable], ItemNotFoundException
+ FullyQualifiedErrorId : VariableNotFound,Microsoft.PowerShell.Commands.RemoveVariableCommand

Remove-Variable : Impossible de trouver une variable assortie du nom « MetadataDefaultHost ».
Au niveau de C:\Users\richardl.EXAKIS\Desktop\MyModule\MyModule.psm1 : 37 Caractère : 53
+ Get-Variable MetadataDefaultHost | Remove-Variable <<<< ; `
+ CategoryInfo : ObjectNotFound: (MetadataDefaultHost:«»String) [Remove-Variable], ItemNotFoundException
+ FullyQualifiedErrorId : VariableNotFound,Microsoft.PowerShell.Commands.RemoveVariableCommand

Remove-Variable : Impossible de trouver une variable assortie du nom « MetadataFolder ».
Au niveau de C:\Users\richardl.EXAKIS\Desktop\MyModule\MyModule.psm1 : 38 Caractère : 48
+ Get-Variable MetadataFolder | Remove-Variable <<<< ; `
+ CategoryInfo : ObjectNotFound: (MetadataFolder:«»String) [Remove-Variable], ItemNotFoundException
+ FullyQualifiedErrorId : VariableNotFound,Microsoft.PowerShell.Commands.RemoveVariableCommand
[/code:1]

Est ce que vous avez une idée d'où provient l'erreur ? (J'ai essayé avec des variables en ReadOnly et sans option la même erreur ...)

Bien Cordialement,
Richard Lazaro.

Message édité par: Richard.L, à: 7/07/10 17:42<br><br>Message édité par: Richard.L, à: 8/07/10 10:39

Think-MS : (Get-Life).Days | %{ Learn-More }

\\"Problems cannot be solved by the same level of thinking that created them.\\" - Albert Einstein

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 13 ans 9 mois #7334 par Laurent Dardenne
Salut,
Richard.L écrit:

Est ce que vous avez une idée d'où provient l'erreur ?

C'est un problème de portée qui n'est pas spécifique au module:
[code:1]
$ModuleFolder=\&quot;C:\Temp\&quot;

Write-host \&quot;remove\&quot;
Remove-Variable ModuleFolder
Write-host \&quot;create\&quot;
$ModuleFolder=\&quot;C:\Temp\&quot;

function Remove {
Get-Variable ModuleFolder
Remove-Variable ModuleFolder -scope 1}
Remove
[/code:1]
Le cmdlet Get-Variable parcourt par défaut toutes les portées pour retrouver la variable indiquée alors que Remove-Variable ne recherche par défaut que dans la portée courante :

-Scope &lt;string&gt;
Spécifie la portée dans laquelle cet alias est valide. Les valeurs valides sont « Global », « Local » ou « Script », ou un nombre relatif à la portée actuelle (0 jusqu'au nombre de portées, où 0 est la portée actuelle et 1 son parent). « Local » est la valeur par défaut. Pour plus d'informations, consultez about_Scopes.

Comme un scriptblock crée une nouvelle portée, on doit lui indiquer dans lequel opérer.
Ce qui fait que si on utilise une fonction pour regrouper les traitements de finalisation on doit préciser -Scope 2 :
[code:1]
$ModuleFolder=\&quot;C:\Temp\&quot;
Function RemoveVar{
Get-Variable ModuleFolder
Remove-Variable ModuleFolder -scope 2
}

$MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = { RemoveVar }
[/code:1]
Et il me semble qu'on peux récupérer le chemin du module courant via une variable...<br><br>Message édité par: Laurent Dardenne, à: 8/07/10 10:09

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 13 ans 9 mois #7335 par Richard Lazaro
hmmm, ok pour la spécificité du Remove-Variable.
Mais ce que je comprends pas c'est pourquoi cela ne fonctionnait pas avec le Get-Variable pipé avec le Remove-Variable ... il devrait pas passer le scope de la variable en même temps ? je trouverais cela logique perso.

J'avais contourné le problème en passant par :
[code:1]Remove-Item Variable:\ModuleFolder -Force[/code:1]

par contre, si tu connais la variable pour le module courant (peut être dans $MyInvocation) ... j'ai essayé avec $pwd mais bien sur comme je me doutais cela ne fonctionne pas ^^

EDIT : J'ai essayé avec le Remove-Variable. Mais pour pouvoir la supprimer, je dois passer 3 au Scope.
Si j'ai bien compris, cela vient du fait que j'instancie mes variables dans un fichier .ps1 que j'appel dans ScriptsToProcess. Ai je bon ?<br><br>Message édité par: Richard.L, à: 8/07/10 10:31

Think-MS : (Get-Life).Days | %{ Learn-More }

\\"Problems cannot be solved by the same level of thinking that created them.\\" - Albert Einstein

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 13 ans 9 mois #7336 par Richard Lazaro
Voilà après quelque recherche pour le chemin :

$MyInvocation.MyCommand.Path

Si je suis dans MyModule/MyModule.psm1
Il me crache tout le chemin complet jusqu'au fichier .psm1

Si je suis dans MyModule/Init.ps1
Il me crache tout le chemin complet jusqu'au fichier .ps1

Merci à toi Laurent de m'avoir éclairé sur la cmdlet Remove-Variable.

Bien Cordialement,
Richard Lazaro.

Think-MS : (Get-Life).Days | %{ Learn-More }

\\"Problems cannot be solved by the same level of thinking that created them.\\" - Albert Einstein

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 13 ans 9 mois #7345 par Laurent Dardenne
Richard.L écrit:

Mais ce que je comprends pas c'est pourquoi cela ne fonctionnait pas avec le Get-Variable pipé avec le Remove-Variable ...

Get-Variable a le même comportement au niveau du scope.
Richard.L écrit:

il devrait pas passer le scope de la variable en même temps ?

Si tu as plusieurs scopes/portées utilisant un même nom de variable lequel doit-il utiliser ? Ces cmdlets ne le savent pas, c'est pour ça que le défaut est \&quot;local\&quot;.
Un exemple où on voit mieux 'l'empilement' des scopes des variables :
[code:1]
$var=\&quot;globale\&quot;
function un {
$var=\&quot;Un\&quot;
function Deux {
$var=\&quot;Deux\&quot;
function trois {
#$var=\&quot;trois\&quot; #test à commenter/décommenter
Remove-Item Variable:\var -Force #test à commenter/décommenter

#$scope=1
#Write-Warning \&quot;Supprime `$var=$((gv var -scope $Scope).Value)\&quot;
#remove-variable var -scope $scope #test à commenter/décommenter
write-host \&quot;Trois: var =$var\&quot;
}#trois
trois
write-host \&quot;Deux: var =$var\&quot;
}
deux
write-host \&quot;un: var =$var\&quot;
}
un
$var
[/code:1]
Reste à tester les différents cas.
Voir aussi cet autre exemple .
Richard.L écrit:

J'avais contourné le problème en passant par :
[code:1]Remove-Item Variable:\ModuleFolder -Force[/code:1]

Remove-Item sur le provider à un comportement différent dans le sens où il parcourt la pile pour supprimer la première occurence trouvée.
C'est une bonne astuce, mais il faut la connaître pour comprendre ce que fait le code, de mon coté je préfére préciser l'intention à l'aide de scope.
L'inconvénient est qu'en cas de modification de portée/réorganisation du code on doit modifier/contrôler la valeur du paramètre scope.
Richard.L écrit:

Si j'ai bien compris, cela vient du fait que j'instancie mes variables dans un fichier .ps1 que j'appel dans ScriptsToProcess. Ai je bon ?

Peut être, comme le script apporte aussi une portée, cf. $script:MaVar, mais je n'ai pas encore utilisé/étudié cette possibilité pour te le confirmer.
Richard.L écrit:

Merci à toi Laurent de m'avoir éclairé sur la cmdlet Remove-Variable.

De rien.

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 13 ans 9 mois #7347 par Richard Lazaro
J'ai précisé le scope, trouvant cela moins \&quot;crade\&quot; :]

Think-MS : (Get-Life).Days | %{ Learn-More }

\\"Problems cannot be solved by the same level of thinking that created them.\\" - Albert Einstein

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.082 secondes
Propulsé par Kunena