Résolu Avis sur un script qui doit corriger des noms de fichiers avec pleins replace

Plus d'informations
il y a 10 mois 1 jour - il y a 10 mois 1 jour #34119 par Alastor
Ca fait sens effectivement.

Du coup, rapport à ton script, tu fais quelque chose comme un "get-content" du fichier xml pour passer dessus ta fonction "ReplaceAllStrings" avant de faire une importation genre "import-clixml" ?

PS : je reconnais avoir pris en otage le sujet... si il ne faut pas dite le moi, on pourra en lancer un autre.
Dernière édition: il y a 10 mois 1 jour par Alastor. Raison: ps

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

Plus d'informations
il y a 10 mois 1 jour - il y a 10 mois 1 jour #34122 par Christophe MELIN
Voilà un exemple de code 

Param(
    [Parameter(Mandatory=$false)][string]$xmlfile=""
)
....
$arrStrings = @( ... )
$defaultxmlstr = '......'
try {
  if ($xmlfile) {
    #-- utilisation du fichier de configuration --
    if ( -not (test-path -Path $xmlfile -PathType Leaf) ) { throw "fichier de config non trouvé ($xmlfile)" }
    $xmlstr = get-content -Path $xmlfile -Raw
  } else {
    #-- utilisation de la configuration par défaut --
    $xmlstr = $defaultxmlstr
  }

  #-- remplacement des chaines de caractères --
  $xmlstr = ReplaceAllStrings -SearchInStr $xmlstr -arrStrings $arrStrings
  #-- conversion de la chaine de caractères en structure XML --
  [xml]$xml= $xmlstr
} catch {
  #-- traitement des erreurs --
  write-host "ERREUR en ligne $($_.invocationinfo.scriptlinenumber)`n$($_.exception.message)" -foregroundcolor red
  exit 1
}
#-- suite du code... --
Dernière édition: il y a 10 mois 1 jour par Christophe MELIN.

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

Plus d'informations
il y a 10 mois 1 jour #34124 par Alastor
J'avais fait la fonction suivante pour un usage dans le genre.
L'usage d'un objet ou d'une hashtable comme donnée d'entrée pour les substitutions me semblait être plus élégant et réutilisable.
function Expand-RefByValInText
{
    <#
        .SYNOPSIS
            Substitue, dans un string, les références aux attributs d'un objet par la valeur de l'attribut.
            Fonctionne également avec une hashtable, ce sont alors les référence aux clefs qui sont remplacées par la valeur correspondante à la clef.
        .VERSION
            1.0
       
        .DESCRIPTION
            Substitue dans un string les références aux attributs de objet, ou aux clefs d'un hashtable, par la valeur de l'attribut ou de la hashtable.
            Les attributs dans la string sont spécifiés entre symbole pourcent, exemple : %SamAccountName%
            ATTENTION : les références aux attributs, ou clefs, doivent respecter la Casse !

        .EXAMPLE
            $UnMessage = "Bonjour %Name%, nous vous sollicitons à propos de votre compte %SamAccountName%"
            $UnUtilisateur = Get-AdUser -Identity "Un SamAccountName"
            $MessagePourUnUtilisateur = Expand-RefByValInText -Object $UnUtilisateur -String $UnMessage

         .NOTES
            Author = Alastor, member of https://powershell-scripting.com/
            Copyright : Creative Commons CC BY-NC-SA
    #>
    param (
        [Parameter(Mandatory)]
        $Object,
        [Parameter(Mandatory)][String]
        $String
    )
    # si le parametre est une hastable
    if (($Object.GetType()).Name -eq "Hashtable") {
        # on va traiter toutes les clefs
        $AllKeys = $Object.keys
        # pour chaque clef
        foreach($AKey in $AllKeys) {
            $CurrentName = $AKey
            $CurrentValue = $Object[$AKey]
   
            $Pattern = "%$($CurrentName)%"
            $ReplacePattern = $CurrentValue
            $String = $String.Replace($Pattern , $ReplacePattern)
        }
    } else {
        # on récupère tous les attributs de l'objet
        $AllProperties = $Object | Get-Member -MemberType Properties
        # pour chaque attribut
        foreach ($AProperty in $AllProperties) {
            $AttributName = $AProperty.name
            $AttributeValue = ($Object).($AProperty.name)
   
            $Pattern = "%$($AttributName)%"
            $ReplacePattern = $AttributeValue
            $String = $String.Replace($Pattern , $ReplacePattern)
        }
    }
    return $String
}

Depuis pour d'autres usages, je l'ai enrichit, avec des échappements des valeurs (html, regexp...), des références taguées, pour pouvoir faire des substitutions les une après les autres avec différents objets etc...

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

Plus d'informations
il y a 10 mois 1 jour #34125 par Arnaud Petitjean
Bonjour à tous,

Effectivement, je rejoins Christophe, c'est une bonne pratique de commencer son script par l'instruction Set-PSDebug -Strict afin de générer une erreur dans la cas où une variable n'est pas initialisée avant d'être utilisée.

Cela étant, je préfère l'utilisation de la commande Set-StrictMode car celle-ci permet d'aller encore plus loin que simplement la non déclaration des variables . Elle offre plusieurs jeux de règles contraintes (version 1, 2 et 3), des moins restrictives aux plus restrictives. Cela permet d'éviter de nombreuses erreurs. 

Pour plus d'infos sur cette commande, je vous suggère d'aller lire son aide :  learn.microsoft.com/fr-fr/powershell/mod....core/set-strictmode

Arnaud

MVP PowerShell et créateur de ce magnifique forum :-)
Auteur de 6 livres PowerShell aux éditions ENI
Fondateur de la société Start-Scripting
Besoin d'une formation PowerShell ?
Les utilisateur(s) suivant ont remercié: Alastor

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

Plus d'informations
il y a 10 mois 1 jour - il y a 10 mois 1 jour #34126 par Alastor
Est-ce qu'il y a une bible des bonnes pratiques PowerShell ?
J'ai trouvé des choses, notamment un module, mais pas LA bible.

Typiquement, est-ce que tenir compte de l'utilisation d'une variable non initialisée n'est pas de la seule responsabilité du développeur et de son débogage ?
Du coup, est-il vraiment recommandé de modifier l'environnement d'exécution ?
Ce qui implique en plus, pour pouvoir à posteriori débogué son script, de commencer par le modifier, avant même de le débuguer, non ?

C'est une vrai question, car c'est la première fois que je croise cette instruction 
Dernière édition: il y a 10 mois 1 jour par Alastor.

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

Plus d'informations
il y a 10 mois 1 jour #34127 par Christophe MELIN
Pour aller dans le sens de Arnaud, OK pour la commande Set-StrictMode qui permet d'être encore plus stricte (mais donc livrer des scripts plus propres). Malheureusement pour moi, je dois faire avec l'existant et jongler entre des serveurs qui vont de Windows Server 2003 à du 2022 (donc des powershell 2.0, 3.0, 4.0, 5.0, 5.1 et suivants). Donc, pour le moment, je m'en tiens au plus "basique".

Concernant la remarque de Alastor, bien sûr que l'utilisation de variables non initialisées est la responsabilité du développeur, mais une faute de frappe est tellement vite arrivée (une simple inversion de caractères par exemple parce qu'une main va plus vite que l'autre) que cette petite commande au début du script évite bien des heures de recherche, surtout quand un script ne donne pas le résultat attendu parce qu'on a fait une faute et qu'on sait pertinemment que l'oeil humain lit ce qu'il "veut" lire quand on fait de la lecture rapide.
Les utilisateur(s) suivant ont remercié: Arnaud Petitjean

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

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