Question Set-RegValue (WMI : StdRegprov)

Plus d'informations
il y a 11 ans 11 mois #11772 par Matthew BETTON
Ci-après un script qui ajoute ou modifie une valeur du registre en local ou sur une machine distante puis redémarre éventuellement un ou plusieurs services, pour prise en compte du nouveau paramétrage.

Pour notamment modifier le registre, j'utilise WMI et la classe StdRegprov. Il y a d'autres solutions.
Dans le cas où WinRM n'est pas installé ou activé, cela peut servir...


[code:1]# Script : Set-RegValue.ps1
# Matthew BETTON
# Le vendredi 11 mai 2012

<#
.SYNOPSIS
Ajoute ou modifie une valeur du registre en local ou sur une machine distante puis redémarre éventuellement un ou plusieurs services.

.DESCRIPTION
Le script 'Set-RegValue.ps1' ajoute une valeur dans le registre ou modifie une valeur du registre déjà existante.

Pré requis : Le chemin du registre dans lequel se trouve(ra) cette valeur doit déjà exister.

Ensuite, ce script peut redémarrer un ou plusieurs services, pour prise en compte du nouveau paramétrage.

Ce script accepte l'entrée du pipeline pour le paramétre '-ComputerName'.

.PARAMETER ComputerName
Spécifie un ordinateur distant. La valeur par défaut est l'ordinateur local.

Tapez le nom NetBIOS, une adresse IP ou le nom de domaine complet d'un ordinateur distant.

Ce paramètre ne s'appuie pas sur la communication à distance Windows PowerShell. Vous pouvez utiliser le paramètre ComputerName
de Set-RegistryValue même si votre ordinateur n'est pas configuré pour exécuter des commandes distantes.

.PARAMETER Credential
Spécifie un compte d'utilisateur qui a l'autorisation d'exécuter cette action. La valeur par défaut est l'utilisateur actuel.

.PARAMETER RegHive
Spécifie la Ruche dans laquelle se trouve la valeur à ajouter ou à modifier.

.PARAMETER RegPath
Spécifie le chemin du registre.

.PARAMETER RegValue
Spécifie un la valeur du registre à ajouter ou à modifier.

.PARAMETER RegType
Spécifie le type de valeur à ajouter ou à modifier.

.PARAMETER RegData
Spécifie la donnée de la valeur du registre.

.PARAMETER RestartService
Spécifie un ou plusieurs services à redémarrer.

.EXAMPLE
C:\PS>$Credential = Get-Credential
C:\PS>.\Set-RegValue.ps1 -ComputerName TORONTO -Credential $Credential -RegHive HKLM -RegPath Software -RegValue MaValeur -RegData 172800 -RegType REG_DWORD

La première ligne de commande récupère un couple login / mot de passe.
La seconde permet d'ajouter une nouvelle valeur dans le registre ou, si elle existe déjà, de la modifier :

[HKLM\Software]
\"MaValeur\" = 172800 (REG_DWORD)

Dans ce cas, la donnée \"172800\" sera une valeur décimale.

.EXAMPLE
C:\PS>.\Set-RegValue.ps1 -ComputerName TORONTO -Credential (Get-Credential CANADA\Matthew) -RegHive HKLM -RegPath SOFTWARE\VERITAS\NetBackup\CurrentVersion\Config -RegValue Buffer_Size -RegData 128 -RegType REG_DWORD -RestartService (\"NetBackup INET Daemon\",\"VBRAgent\"«»)

Cette ligne de commande commence par demander un mot de passe pour le compte 'CANADA\Matthew'.
Ensuite elle modifie le registre avec la valeur suivante :

[HKLM\SOFTWARE\VERITAS\NetBackup\CurrentVersion\Config]
\"Buffer_Size\" = 128 (REG_DWORD)

Enfin, elle redémarre successivement les services \"NetBackup INET Daemon\" puis \"VBRAgent\", pour prise en compte du nouveau paramétrage.

.EXAMPLE
PS> \"CATOSV01\", \"CATODC01\", \"localhost\" | .\Set-RegValue.ps1 -RegHive HKLM -RegPath \"System\CurrentControlSet\Services\HTTP\Parameters\" -RegValue MaxFieldLength -RegData 65534 -RegType REG_DWORD
PS> \"CATOSV01\", \"CATODC01\", \"localhost\" | .\Set-RegValue.ps1 -RegHive HKLM -RegPath \"System\CurrentControlSet\Services\HTTP\Parameters\" -RegValue MaxRequestBytes -RegData 65534 -RegType REG_DWORD -RestartService HTTP

La première ligne de commande permet d'ajouter ou de modifier la valeur du registre suivante :

[HKLM\System\CurrentControlSet\Services\HTTP\Parameters]
\"MaxFieldLength\" = 65534 (REG_DWORD)

La seconde ligne de commande permet d'ajouter ou de modifier la valeur du registre suivante :

[HKLM\System\CurrentControlSet\Services\HTTP\Parameters]
\"MaxRequestBytes\" = 65534 (REG_DWORD)

Enfin, elle redémarre le service \"HTTP\" pour prise en compte du nouveau paramétrage.

.OUTPUT
Un fichier journal nommé avec la date du jour de l'exécution du script et situé dans le répertoire d'exécution du script.
#>


[CmdletBinding(SupportsShouldProcess=$true)]
param(
[Parameter(Position=0,Mandatory=$False,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
[Alias(\"cn\",\"Computer\"«»)]
[String[]]$ComputerName = \"localhost\",
[Parameter(Mandatory=$False)]
[System.Management.Automation.PSCredential]$Credential=[System.Management.Automation.PSCredential]::Empty,
[Parameter(Mandatory=$True)]
[ValidateSet(\"HKLM\",\"HKU\"«»)]
[String]$RegHive = \"HKLM\",
[Parameter(Mandatory=$True)]
[String]$RegPath,
[Parameter(Mandatory=$True)]
[String]$RegValue,
[Parameter(Mandatory=$True)]
[ValidateSet(\"REG_DWORD\",\"REG_BINARY\",\"REG_SZ\",\"REG_MULTI_SZ\",\"REG_EXPAND_SZ\"«»)]
[String]$RegType = \"REG_DWORD\",
[Parameter(Mandatory=$True)]
$RegData,
[Parameter(Mandatory=$False)]
[String[]]$RestartService
)

Begin{

Function Test-WMIConnection(){

<#
.SYNOPSIS
Test si la connexion WMI est OK.

.DESCRIPTION
La fonction 'Test-WMIConnection' test si la connexion WMI d'une machine distante est OK.

.PARAMETER ComputerName
Spécifie un ordinateur distant. La valeur par défaut est l'ordinateur local.

Tapez le nom NetBIOS, une adresse IP ou le nom de domaine complet d'un ordinateur distant.

Ce paramètre ne s'appuie pas sur la communication à distance Windows PowerShell. Vous pouvez utiliser le paramètre ComputerName
de Test-WMIConnection même si votre ordinateur n'est pas configuré pour exécuter des commandes distantes.

.PARAMETER Credential
Spécifie un compte d'utilisateur qui a l'autorisation d'exécuter cette action. La valeur par défaut est l'utilisateur actuel.

.EXAMPLE
C:\PS>$Credential = Get-Credential
C:\PS>Test-WMIConnection -ComputerName TORONTO -Credential $Credential

Permet de tester la connexion WMI sur la machine nommée TORONTO.

.OUTPUT
$True si la connexion WMI est OK.
$False si ce n'est pas le cas.

#>

param(
[Parameter(Mandatory=$true)]
[String]$ComputerName,
[Parameter(Mandatory=$true)]
[System.Management.Automation.PSCredential]$Credential
)

Write-Verbose \"Fonction 'Test-WMIConnection' : $ComputerName / $($Credential.UserName)\"

try{
$result = Get-WmiObject -Class Win32_BIOS -Namespace 'root\cimv2' -ComputerName $ComputerName -Credential $Credential -ErrorAction Stop
}
catch{
Set-Error \"Problème lors du test de connexion WMI sur '$ComputerName' : $($error[0].Exception.Message)\"
return $false
}

return $true
}

# Fonction d'affichage des informations d'avancement dans la console et dans le fichier log
Function Write-Log(){

<#
.SYNOPSIS
Ecrit dans un fichier log.

.DESCRIPTION
La fonction 'Write-Log' permet d'écrire des informations dans un fichier log.
Le fichier log est généré dans le répertoire d'exécution du script.
Il est nommé avec la date courante.
Si le log existe déjà, les informations y sont ajoutées.

.PARAMETER Message
Indique le message qui sera ajouté au fichier journal.

.EXAMPLE
C:\PS>Write-Log \"Mon Message d'informations\"

Permet d'ajouter le texte \"Mon Message d'informations\" au fichier journal.

#>

param(
[Parameter(Mandatory=$true)]
[String]$Message
)

Write-Verbose \"Fonction 'Write-Log' : $Message\"
Write-Debug $Message
Write-Output $Message | Out-File -Append -Encoding \"Default\" -FilePath $LogFile
}

Function Set-Error(){

<#
.SYNOPSIS
Trace une erreur dans la console et un fichier de log.

.DESCRIPTION
La fonction 'Set-Error' permet d'écrire des informations à propos d'une erreur dans un fichier log.
L'erreur est redirigée vers la console.

.PARAMETER ErrMsg
Indique le message d'erreur qui sera ajouté au fichier journal et affiché dans la console.

.EXAMPLE
C:\PS>Set-Error \"Mon message d'erreur\"

Affiche le message d'erreur \"Mon message d'erreur\" et l'ajoute au fichier journal.

#>

param(
[Parameter(Mandatory=$true)]
[String]$ErrMsg
)

Write-Verbose \"Fonction 'Set-Error' : $ErrMsg\"

Write-Log -Message $ErrMsg
Write-Error $ErrMsg
}

# Fonction de modification ou d'ajout d'une valeur dans le registre distant
# ATTENTION : l'arboressence de destination (la clef) doit déjà exister !
Function Set-RegistryValue(){
param(
[Parameter(Mandatory=$true)]
[String]$ComputerName,
[Parameter(Mandatory=$true)]
[System.Management.Automation.PSCredential]$Credential,
[Parameter(Mandatory=$true)]
[String]$Hive,
[Parameter(Mandatory=$true)]
[String]$Path,
[Parameter(Mandatory=$true)]
[String]$Value,
[Parameter(Mandatory=$true)]
[String]$Type,
[Parameter(Mandatory=$true)]
$Data
)

<#
.SYNOPSIS
Ajoute ou modifie une valeur du registre en local ou sur une machine distante.

.DESCRIPTION
La fonction 'Set-RegistryValue' ajoute une valeur dans le registre ou modifie une valeur du registre déjà existante.

Pré requis : Le chemin du registre dans lequel se trouve cette valeur doit déjà exister.

.PARAMETER ComputerName
Spécifie un ordinateur distant. La valeur par défaut est l'ordinateur local.

Tapez le nom NetBIOS, une adresse IP ou le nom de domaine complet d'un ordinateur distant.

Ce paramètre ne s'appuie pas sur la communication à distance Windows PowerShell. Vous pouvez utiliser le paramètre ComputerName
de Set-RegistryValue même si votre ordinateur n'est pas configuré pour exécuter des commandes distantes.

.PARAMETER Credential
Spécifie un compte d'utilisateur qui a l'autorisation d'exécuter cette action. La valeur par défaut est l'utilisateur actuel.

.PARAMETER Hive
Spécifie la Ruche dans laquelle se trouve la valeur à ajouter ou à modifier.

.PARAMETER Path
Spécifie le sous-chemin du registre.

.PARAMETER Value
Spécifie un la valeur du registre à ajouter ou à modifier.

.PARAMETER Type
Spécifie le type de valeur à ajouter ou à modifier.

.PARAMETER Data
Spécifie la donnée de la valeur du registre.

.EXAMPLE
C:\PS>$Credential = Get-Credential
C:\PS>Set-RegistryValue -ComputerName TORONTO -Credential $Credential -Hive HKLM -Path Software -Value MaValeur -Data 172800 -Type REG_DWORD

Permet d'ajouter une nouvelle valeur dans le registre ou, si elle existe de la modifier :

[HKLM\Software]
\"MaValeur\" = 172800 (REG_DWORD)

Dans ce cas, la donnée \"172800\" sera une valeur décimale.

.OUTPUT
$True si la modification du registre s'est correctement déroulée.
$False si ce n'est pas le cas.
#>

Write-Verbose \"Fonction 'Set-RegistryValue' : $ComputerName / $($Credential.UserName) / $Hive / $Path / $Value / $Type / $Data\"

try{
$objReg = ((Get-WmiObject -list -namespace root\default -computerName $ComputerName -credential $Credential -ErrorAction Stop) | where-object { $_.name -eq \"StdRegProv\" })
}
catch{
Set-Error \"Une erreur s'est produite lors de l'accès à la classe StdRegprov sur $ComputerName : $($error[0].Exception.Message)\"
return $false
}

Switch($Hive){
\"HKLM\" {$hDefKey = 2147483650}
\"HKU\" {$hDefKey = 2147483651}
default {$hDefKey = 2147483650}
}

$result = $objreg.EnumKey($hDefKey, $Path)

if($result.ReturnValue -ne 0){
Set-Error \"Le chemin du registre '$Hive\$Path' n'a pas été trouvé sur '$ComputerName'.`nLa valeur ne sera pas ajoutée.\"
return $false
}

Write-Log \"Modification de la valeur '$Value' présente dans la ruche '$Hive\$Path' sur '$ComputerName' avec la donnée '$Data' ...\"

If ($pscmdlet.ShouldProcess($ComputerName)) {
Switch($RegType){

\"REG_DWORD\" {
$result = $objreg.SetDWORDValue($hDefKey,$Path,$Value,$Data)
}
\"REG_BINARY\" {
$result = $objreg.SetBinaryValue($hDefKey, $Path,$Value, $Data)
}
\"REG_SZ\" {
$result = $objreg.SetStringValue($hDefKey, $Path,$Value, $Data)
}
\"REG_MULTI_SZ\" {
$result = $objreg.SetMultiStringValue($hDefKey, $Path,$Value, $Data)
}
\"REG_EXPAND_SZ\" {
$result = $objreg.SetExpandedStringValue($hDefKey, $Path,$Value, $Data)
}
}

if($result.ReturnValue -ne 0){
Set-Error \"Une erreur s'est produite lors de la modification du registre sur '$ComputerName' : $($result.ReturnValue)\"
return $false
}
}
else{
Write-Host \"Modification de la valeur '$Value' présente dans la ruche '$Hive\$Path' sur '$ComputerName' avec la donnée '$Data' effectuée\"
}

$objreg = $null

return $true

}

# Fonction de redémarage d'un service à distance
Function Restart-RemoteService(){

<#
.SYNOPSIS
Redémarre un service en local ou sur une machine distante.

.DESCRIPTION
La fonction 'Restart-RemoteService' permet de redémarrer un service en local ou sur une machine distante.

.PARAMETER ComputerName
Spécifie un ordinateur distant. La valeur par défaut est l'ordinateur local.

Tapez le nom NetBIOS, une adresse IP ou le nom de domaine complet d'un ordinateur distant.

Ce paramètre ne s'appuie pas sur la communication à distance Windows PowerShell. Vous pouvez utiliser le paramètre ComputerName
de Set-RegistryValue même si votre ordinateur n'est pas configuré pour exécuter des commandes distantes.

.PARAMETER Credential
Spécifie un compte d'utilisateur qui a l'autorisation d'exécuter cette action. La valeur par défaut est l'utilisateur actuel.

.PARAMETER Service
Spécifie le nom du service à redémarrer.

.EXAMPLE
C:\PS>$Credential = Get-Credential
C:\PS>Restart-RemoteService -ComputerName TORONTO -Credential $Credential -Service WinRM

La première ligne de commande récupère un compte / mot de passe.
La seconde ligne de commande permet de redémarrer le service 'WinRM' sur la machine nommée TORONTO.

.OUTPUT
$True si le redémarrage du service s'est correctement déroulé.
$False si ce n'est pas le cas.
#>


param(
[String]$ComputerName,
[System.Management.Automation.PSCredential]$Credential,
[String]$Service
)

Write-Verbose \"Fonction 'Restart-RemoteService' : $ComputerName / $Service\"

try{
$MyService = (Get-WmiObject -computer $ComputerName -Credential $Credential -Class Win32_Service -Filter \"Name='$Service'\" -ErrorAction Stop)
}
catch{
Set-Error \"Erreur lors de la récupération du service '$Service' sur '$ComputerName' : $($_.Exception.Message)\"
return $false
}

If ($pscmdlet.ShouldProcess($ComputerName)) {
Write-Log \"Arrêt du service '$Service' sur '$ComputerName' ...\"
$ErrSvc = $MyService.StopService()
if($ErrSvc.ReturnValue -ne 0){
Set-Error \"Erreur lors de l'arrêt du service '$Service' sur '$ComputerName' : $($ErrSvc.ReturnValue)\"
return $false
}
else{
Write-Log \"Arrêt du service '$Service' sur '$ComputerName' : OK\"
$Time = 0
$BoolSvcStopped = $False

while($Time -le 60){
Start-Sleep -Seconds 1
try{
$MyService = (Get-WmiObject -ComputerName $ComputerName -Credential $Credential -Class Win32_Service -Filter \"Name='$Service'\" -ErrorAction Stop)
}
catch{
Set-Error \"Erreur lors de la récupération du service '$Service' sur '$ComputerName' : $($_.Exception.Message)\"
return $false
}
if($MyService.State -eq \"Stopped\"«»){
$BoolSvcStopped = $true
$Time = 60
}
$Time ++
}

if($BoolSvcStopped){
Write-Log \"Démarrage du service '$Service' sur '$ComputerName' ...\"
$ErrSvc = $MyService.StartService()
if($ErrSvc.ReturnValue -ne 0){
Set-Error \"Erreur lors du démarrage du service '$Service' sur '$ComputerName' : $($ErrSvc.ReturnValue)\"
return $false
}
else{
Write-Log -Message \"Démarrage du service '$Service' sur '$ComputerName' : OK\"
$MyService = $null
return $true
}
}
else{
Set-Error \"Le service '$Service' ne s'est pas arrêté dans le temps imparti !\"
return $false
}
}
}
else{
Write-Host \"Redémarrage du service '$Service' sur '$ComputerName' effectué\"
}
}

$LogDate = (Get-Date).ToString(\"MM_dd_yyyy\"«»)
$Global:LogFile = \".\$($LogDate)_Set-RegValue.log\"
Write-Log \"`n`n\"
Write-Log \"Lancement du traitement le $((Get-Date).ToString())\"
}

Process{

Foreach($Computer in $ComputerName){
Write-Log \"`nMachine en cours de traitement : $Computer\"

if(($Computer -eq \"localhost\"«») -or ($Computer -eq \".\"«»)){
If (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] \"Administrator\"«»)){
Set-Error \"Ce script nécessite des droits d'administrateur pour être exécuté en local. Le paramétre '-Credential' ne peut pas être utilisé pour des connexions locales.\"
Continue
}
}

if(Test-Connection -ComputerName $Computer -Count 1 -Quiet){
if((Test-WMIConnection -ComputerName $Computer -Credential $Credential)){

Set-RegistryValue -ComputerName $Computer -Credential $Credential -Hive $RegHive -Path $RegPath -Value $RegValue -Type $RegType -Data $RegData | Out-Null

if($RestartService){
Foreach($Svc in $RestartService){
Restart-RemoteService -ComputerName $Computer -Credential $Credential -Service $Svc | Out-Null
}
}
}
else{
Set-Error \"Erreur de connexion WMI sur '$Computer'\"
}
}
else{
Set-Error \"'$Computer' est injoignable.\"
}

}

}

End{
Write-Log \"Fin du traitement le $((Get-Date).ToString())\"
}[/code:1]

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

Plus d'informations
il y a 11 ans 11 mois #11773 par SiSMik
Réponse de SiSMik sur le sujet Re:Set-RegValue (WMI : StdRegprov)
J'aime bien, c'est bien commenté/documenté.
Je testerais ça lundi, ça pourrait me servir potentiellement !

Je vois que toi aussi tu es obligé de faire une fonction de log perso, c'est dramatique qu'il n'y ait pas ça en natif dans Powershell. On en avait parlé avec Laurent sur un autre post.

Je pense que à la prochaine accalmie ça sera important de s'y coller !

Joli script en tout cas, toutes mes ficelles de caleçon :)

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

Plus d'informations
il y a 11 ans 11 mois #11778 par Matthew BETTON
Salut,

Merci benduru pour ton commentaire. Merci également pour ton tweet ;)

Je ne suis pas encore habitué à cette techno de communication... Mais je vais m'y mettre :)

Pour les logs, oui je suis un habitué. Il est souvent important de tracer, d'avoir un niveau d'information minimum pour savoir ce qui s'est passé.

C'est un manque, mais je ne trouve pas ça si compliqué. C'était pire en vbs :P

Merci et @+

Matthew

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

Plus d'informations
il y a 11 ans 11 mois #11779 par Matthew BETTON
... J'ajoute qu'il sera intéressant de présenter les mêmes actions mais cette fois-ci via WinRM :)<br><br>Message édité par: Matthew BETTON, à: 12/05/12 14:31

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

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