IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Scripts/Batch Discussion :

Gestion erreurs avec $Error [PowerShell]


Sujet :

Scripts/Batch

  1. #1
    Membre confirmé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Points : 460
    Points
    460
    Par défaut Gestion erreurs avec $Error
    Bonjour,

    Je suis en train de me battre pour gérer certaines erreurs et notamment celles qui concernent le fait qu'une commande n'est pas connue par une version x de powershell.

    Typiquement,

    > Cette erreur est correctement détectée par le script :

    Pas connu en PS 2.0 et le scirpt sort bien en erreur
    Code Powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    $file_list = Get-ChildItem -Path $($src+'\'+$file) -File

    Equivalent OK en PS 2.0
    Code Powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    $file_list = Get-ChildItem -Path $($src+'\'+$file) | Where { !$_.PSIsContainer }

    > En revanche, celle ci n'est pas correctement traitée par le script. Il ne sort pas en erreur et je comprends pas pourquoi.

    Pas connu en PS 2.0 et le script ne sort pas en erreur
    Code Powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        if ( $false -in $success_list ) 
        { # Vérifier s'il y a eu des erreurs propres au déroulement de la fonction 
            $count = 0 ; foreach ( $v in $false_list ) { $count ++ }
            Write-Host `n'> ERREUR : Erreur(s) de déplacement constatée(s) : ['$count']'
        }

    Equivalent OK en PS 2.0
    Code Powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        $false_list = ( $success_list | Where { $_ -eq $false } )
        if ( $false_list -ne $null )
        { # Vérifier s'il y a eu des erreurs propres au déroulement de la fonction 
            $count = 0 ; foreach ( $v in $false_list ) { $count ++ }
            Write-Host `n'> ERREUR : Erreur(s) de déplacement constatée(s) : ['$count']'
        }

    > Remarque

    j'écris :
    Code Powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    $count = 0 ; foreach ( $v in $false_list ) { $count ++ }

    au lieu de :

    Code Powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    $count = $false_list.Count

    Car j'ai remarqué qu'en PS 2.0, si la liste est positive avec 0 ou 1 élément, la méthode .Count renvoi $null. "Cela fonctionne" que s'il y a 2 éléments ou plus dans le tableau. Je n'ai pas trouvé de réponse à cela mais je contourne de la sorte.
    Néanmoins pour la variable $Error, la méthode .Count a un comportement normal s'il y a 0 ou 1 erreur en PS 2.0. Je ne sais trop quoi en penser vis à vis de ma dernière remarque.

    > Pour information le script retourne la variable $CR pour statuer ou non le bon déroulement de celui-ci. Si $CR = 0, exécution du script OK et si $CR > 0, exécution du script NOK.

    > Voici le code complet. Concrètement, je cherche à expliquer pourquoi l'erreur 1 est traitée ( $CR > 1 ) et pas l'erreur 2 ( $CR = 0 ).

    En vous remerciant par avance pour votre aide.

    Code Powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    ### VARIABLES ###
     
    $src  = $args[0]
    $dst  = $args[1]
    $file = $args[2]
     
    ##### Fonctions #####
     
    Function Ctrl-Path ( $path, $commentary )
    {
        $success = $false
    	if ((Test-Path -Path $path) -eq $True)
    	{
    		Write-Host `n'> Le Répertoire '$commentary' '$path' existe'
            $success = $true
    	} 
        else 
        {
    		Write-Host `n'> Le Répertoire '$commentary' '$path' n''existe pas'
     
    	}
        return $success
    }
     
     
    Function Get-FileList ( $file )
    {
        $file_list = $null
        if ( ( $file -eq '*' ) -or ( $file -match '`*.' ) )
    	{
            Write-Host `n'> Chemin canonique : '$($src+'\'+$file)
    		$file_list = Get-ChildItem -Path $($src+'\'+$file) | Where { !$_.PSIsContainer }
    	}
    	else { $file_list += $file }
        return $file_list
    }
     
    Function Move-ItemArchive( $src, $dst )
    {
        $success = $true
        if ( ( $a = Test-Path -Path $($f.FullName) ) -and !( $b = Test-Path $($dst+'\'+$f.Name) ) )
    	{
    		Move-item $($f.FullName) -Destination $dst
     
            if ( !( $a = Test-Path -Path $($f.FullName) ) -and ( $b = Test-Path $($dst+'\'+$f.Name) ) )
            { # Le fichier déplacé est présent dans le repertoire de destination et n'est plus présent dans le répertoire source
                Write-Host OK
            } 
            else  
    		{ # Erreur lors du déplacement du fichier : Le fichier déplacé n'est pas présent dans le repertoire de destination
    			$success = $false
    			if (  $a ) 
    			{
    				Write-Host NOK
    				Write-Host '      - Erreur : Le fichier est toujours présent dans le répertoire source'
    			}
    			if ( !$b )
    			{
    				Write-Host NOK
    				Write-Host '      - Erreur : Le fichier n''estpas présent dans le répertoire destination'
    			}
    		}
    	}
    	else
    	{
    		$success = $false
    		if ( !$a ) 
    		{
    			Write-Host NOK
    			Write-Host '      - Erreur : Le fichier source n''existe pas dans le repertoire source'
    		}
    		if (  $b )
    		{
    			Write-Host NOK
    			Write-Host '      - Erreur : Le fichier source existe déjà dans le répertoire destination'
    		}
    	}
        return $success
    }
     
    Function archive
    {
        Write-Host `n'> Début de l''archivage'
        $success = $false   ; # Variable qui détermine le bon déroulement ou non de la fonction
        $success_list = @() ; # Variable qui détermine s'il y a eu une ou plusieurs erreur durant les déplacements de fichers
    	$file_list    = @() ; # Initialisation de la variable qui va contenir la liste des fichiers présents dans le répertoire source
        $file_count   = 0   ; # Variable qui compte le nombre de fichiers présents dans le répertoire source
     
        if ( ( Ctrl-Path -path $src -commentary "source" ) -and ( Ctrl-Path -path $dst -commentary "destination" ) )
        {
            $file_list = Get-FileList -file $file
     
    	    if ( $file_list -ne $null )
    	    { # On vérifie qu'il y a des fichiers à déplacer 
    		    foreach ( $f in $file_list ) { $file_count++ }
                Write-Host `n'> ['$file_count'] fichier(s) présent(s) en argument'
     
                $index = 0 ; 
    		    foreach ( $f in $file_list )
    		    { # Début de la boucle de déplacement du ou des fichiers
    			    Write-Host '   > Début de l''archivage du fichier '($index+1)/$file_count' :'
    			    Write-Host '    + Src : ' $($f.FullName)
    			    Write-Host '    + Dst : ' $dst
    			    Write-Host '    + Status : ' -NoNeWLine 
     
                    $success_list += Move-ItemArchive -src $f -dst $dst
                    $index        += 1
    		    }
    	    }
    	    else 
            { # S'il n'y a pas de fichier à déplacer ( pas considéré comme une erreur )
                if ( $Error.Count -eq 0 ) 
                { # On vérifie qu'il n'y a pas eu d'erreur dans logs d'erreurs std pour s'assurer que la cause n'est pas inhérente à une ou plusieurs erreurs powershell préalables mais bien au fait qu'il n'y ait aucun fichier correspondant aux critères
                    Write-Host `n'> ATTENTION : Aucun fichier répondant au(x) critère(s)"' $file '" n''est présent dans le répertoire source' 
                }
                # Sinon on continue l'execution du script jusqu'au controle de la log d'erreur std
            }
        }
        else { $success_list += $false } 
     
        $false_list = ( $success_list | Where { $_ -eq $false } )
        if ( $false -in $success_list ) #$false_list -ne $null
        { # Vérifier s'il y a eu des erreurs propres au déroulement de la fonction 
            $count = 0 ; foreach ( $v in $false_list ) { $count ++ }
            Write-Host `n'> ERREUR : Erreur(s) de déplacement constatées : ['$count']'
        }
        else 
        {
            Write-Host `n'> Aucune erreur de déplacement n''a été constatée'
            $success = $true 
        }
        Write-Host `n'> Fin de l''archivage'
        return $success 
    }
     
    Function Main-Function
    {
        $r = @(1,1)
     
        if ( ($success = archive) ) { $r[0] = 0 }
     
        if ( $Error.Count -ne 0 )
        { # Liste des erreurs inhérentes à powershell
            Write-Host `n'> ERREUR : Liste des erreurs survenues lors de l''éxecution de la fonction : ( Voir la log d''erreur pour plus de détails )'
            foreach ( $err in $Error ) { Write-Host '+ '$err }
        }
        else { $r[1] = 0 }
     
        return $( $r[0] + $r[1] )
    }
     
    ##### Main #####
    $CR = 1
    $Error.Clear | Out-Null
    $CR = Main-Function
    Exit $CR
     
    ###FIN###
    UNE REPONSE UTILE : &|| UN PROBLEME RESOLU :

  2. #2
    Expert confirmé

    Homme Profil pro
    Responsable déploiement (SCCM, InTune, GPO)
    Inscrit en
    Juillet 2014
    Messages
    3 184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Responsable déploiement (SCCM, InTune, GPO)
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2014
    Messages : 3 184
    Points : 5 755
    Points
    5 755
    Par défaut
    Je ne vois pas d'erreur, c'est quoi l'erreur ?





    Car j'ai remarqué qu'en PS 2.0, si la liste est positive avec 0 ou 1 élément, la méthode .Count renvoi $null. "Cela fonctionne" que s'il y a 2 éléments ou plus dans le tableau. Je n'ai pas trouvé de réponse à cela mais je contourne de la sorte.
    Tu doit forcer le type :
    Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    @($false_list).Count




    Si ton script doit tourner sur plusieurs versions de Powershell il doit fonctionner sur la plus petite. Tu peux aussi imposer une version minimal si besoin.
    Autrement dit tu devrait faire que
    Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    $file_list = Get-ChildItem -Path $($src+'\'+$file) | Where { !$_.PSIsContainer }
    et pas
    Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    $file_list = Get-ChildItem -Path $($src+'\'+$file) -File




    Sinon je ne comprend pas trop le script, pourquoi semble t'il si volumineux pour une simple copie de fichier ?
    Tu doit être débutant en Powershell je pense ?
    Exemple, ceci me parait beaucoup plus clair que ton code :
    Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Function Ctrl-Path ( $path, $commentary )
    {
        $result = Test-Path -Path $path
        if ($result)
        {
            Write-Host `n'> Le Répertoire '$commentary' '$path' existe'
        } 
        else 
        {
            Write-Host `n'> Le Répertoire '$commentary' '$path' n''existe pas'
        }
        return $result
    }

  3. #3
    Expert confirmé

    Homme Profil pro
    Responsable déploiement (SCCM, InTune, GPO)
    Inscrit en
    Juillet 2014
    Messages
    3 184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Responsable déploiement (SCCM, InTune, GPO)
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2014
    Messages : 3 184
    Points : 5 755
    Points
    5 755
    Par défaut
    Tu devrais aussi te pencher sur le try catch pour la gestion d'erreur

  4. #4
    Membre confirmé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Points : 460
    Points
    460
    Par défaut
    Citation Envoyé par ericlm128 Voir le message
    Je ne vois pas d'erreur, c'est quoi l'erreur ?
    -File sort le script en erreur i.e CR > 0
    -in ne sort pas le script en erreur i.e CR=0 alors que comme précisé -in n'est pas connu en PS 2.0 tout comme -File

    Tu doit forcer le type :
    Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    @($false_list).Count
    Je prends note, merci

    Si ton script doit tourner sur plusieurs versions de Powershell il doit fonctionner sur la plus petite. Tu peux aussi imposer une version minimal si besoin.
    Autrement dit tu devrait faire que
    Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    $file_list = Get-ChildItem -Path $($src+'\'+$file) | Where { !$_.PSIsContainer }
    et pas
    Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    $file_list = Get-ChildItem -Path $($src+'\'+$file) -File
    Oui, je sais bien, ce n'est pas la question. Vous vous doutez bien qu'ayant la réponse, je pourrais très bien substituer la commande 1 à la commande 2 et passer à autre chose.
    Le script est utilisé sur différents ordonnanceurs qui exécutent le script à partir de différents agents dont les versions PS diffèrent.
    Par sécurité, toutes erreurs constatées doit sortir le script en erreur peu importe la version PS en fait. Dans ce cas, il s'agit de ça effectivement mais il ne s'agit pas que de ce point en particulier.
    Le fait est que comme je l'ai précisé, le script sort en erreur quand j'utilise cette commande

    Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    $file_list = Get-ChildItem -Path $($src+'\'+$file) -File

    Ce qui est le comportement attendu. Mais pas celle-ci qui utilise '-in' alors qu'il s'agit du même type d'erreur.


    Sinon je ne comprend pas trop le script, pourquoi semble t'il si volumineux pour une simple copie de fichier ?
    Tu doit être débutant en Powershell je pense ?
    Exemple, ceci me parait beaucoup plus clair que ton code :
    Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Function Ctrl-Path ( $path, $commentary )
    {
        $result = Test-Path -Path $path
        if ($result)
        {
            Write-Host `n'> Le Répertoire '$commentary' '$path' existe'
        } 
        else 
        {
            Write-Host `n'> Le Répertoire '$commentary' '$path' n''existe pas'
        }
        return $result
    }
    EDIT : J'ai pas compris la remarque. Oui, c'est une autre façon de l'écrire, j'ai repris le code de quelqu'un d'autre, je ne prétends pas que le code soit parfait en terme de lisibilité. Pour le moment, ce n'est pas le sujet même si la remarque est à faire. Bref.

    Je suis ni débutant ni expert et je ne vois pas en quoi cette fonction procède à un déplacement de fichier ?
    Vous vous doutez bien que s'il y a autant de checks et de verbose pour faire le déplacement c'est bien que la simple fonction move-item ne répond pas au cahier des charges imposé. Je ne vais pas rentrer dans le détail, ce n'est pas le sujet tout comme le fait que je sois débutant ou non. Je ne vois pas l'intérêt de procéder à ce genre de jugement de valeur ici.
    UNE REPONSE UTILE : &|| UN PROBLEME RESOLU :

  5. #5
    Membre confirmé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Points : 460
    Points
    460
    Par défaut
    Citation Envoyé par ericlm128 Voir le message
    Tu devrais aussi te pencher sur le try catch pour la gestion d'erreur
    C'est une solution pour le moment non envisagée.
    Je souhaiterais déjà comprendre pourquoi le comportement du script est incohérent.
    Pourquoi -File sort en erreur et pas -in.

    Si y'a pas de réponse ou solution, je changerai de méthode en effet.
    UNE REPONSE UTILE : &|| UN PROBLEME RESOLU :

  6. #6
    Expert confirmé

    Homme Profil pro
    Responsable déploiement (SCCM, InTune, GPO)
    Inscrit en
    Juillet 2014
    Messages
    3 184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Responsable déploiement (SCCM, InTune, GPO)
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2014
    Messages : 3 184
    Points : 5 755
    Points
    5 755
    Par défaut
    Je suis ni débutant ni expert et je ne vois pas en quoi cette fonction procède à un déplacement de fichier ?
    Vous vous doutez bien que s'il y a autant de checks et de verbose pour faire le déplacement c'est bien que la simple fonction move-item ne répond pas au cahier des charges imposé. Je ne vais pas rentrer dans le détail, ce n'est pas le sujet tout comme le fait que je sois débutant ou non. Je ne vois pas l'intérêt de procéder à ce genre de jugement de valeur ici.
    Excuse moi si je t'ai froissé mais ce n'est pas péjoratif, connaitre le niveau de l'interlocuteur peut être pratique pour discuter.



    in ne semble pas exister en PS 2.0 mais tu a contains
    Ce que je veux dire c'est qu'il est plus pratique de faire un code qui ne génèrera pas d'erreur plutôt que d'en générer quasiment volontairement et les traiter ensuite. C'est la bonne pratique a suivre je pense.




    -File sort le script en erreur i.e CR > 0
    -in ne sort pas le script en erreur i.e CR=0 alors que comme précisé -in n'est pas connu en PS 2.0 tout comme -File
    Je n'ai pas de PS 2.0 pour reproduire exactement ton phénomène mais ce code avec un opérateur inconnu me génère bien une erreur :
    Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    PS C:\Users\ericlm128> "toto" -trtr "aza"
    Au caractère Ligne:1 : 8
    + "toto" -trtr "aza"
    +        ~~~~~
    Jeton inattendu «*-trtr*» dans l’expression ou l’instruction.
    Au caractère Ligne:1 : 14
    + "toto" -trtr "aza"
    +              ~~~~~
    Jeton inattendu «*"aza"*» dans l’expression ou l’instruction.
        + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
        + FullyQualifiedErrorId : UnexpectedToken
    D'ailleurs ce n'est pas une erreur d'exécution mais de "compilation", autrement dit il n'exécute même pas le code car il y a détecté une erreur de syntaxe grave et gérée lors de l'analyse du code pré-exécution

  7. #7
    Membre confirmé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Points : 460
    Points
    460
    Par défaut
    Citation Envoyé par ericlm128 Voir le message
    Excuse moi si je t'ai froissé mais ce n'est pas péjoratif, connaitre le niveau de l'interlocuteur peut être pratique pour discuter.
    Pas de souci, j'ai pas de problème avec le fait d'être débutant ou non. Je n'ai pas compris le but de la remarque mais maintenant je comprends mieux la démarche.


    in ne semble pas exister en PS 2.0 mais tu a contains
    Ce que je veux dire c'est qu'il est plus pratique de faire un code qui ne génèrera pas d'erreur plutôt que d'en générer quasiment volontairement et les traiter ensuite. C'est la bonne pratique a suivre je pense.
    Effectivement, c'est plus logique. J'essaie de tester des comportements pour éviter que cela ne se reproduise à l'avenir. En l'occurrence, cette erreur n'a pas été détectée tout de suite ( -File ) et foutu un peu le bordel. J'essaie juste de comprendre pour ne pas reproduire. Cela n'a pas vocation à rester tel quel.


    Je n'ai pas de PS 2.0 pour reproduire exactement ton phénomène mais ce code avec un opérateur inconnu me génère bien une erreur :
    Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    PS C:\Users\ericlm128> "toto" -trtr "aza"
    Au caractère Ligne:1 : 8
    + "toto" -trtr "aza"
    +        ~~~~~
    Jeton inattendu «*-trtr*» dans l’expression ou l’instruction.
    Au caractère Ligne:1 : 14
    + "toto" -trtr "aza"
    +              ~~~~~
    Jeton inattendu «*"aza"*» dans l’expression ou l’instruction.
        + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
        + FullyQualifiedErrorId : UnexpectedToken


    D'ailleurs ce n'est pas une erreur d'exécution mais de "compilation", autrement dit il n'exécute même pas le code car il y a détecté une erreur de syntaxe grave et gérée lors de l'analyse du code pré-exécution
    [/QUOTE]

    Ah super merci, c'est la subtilité qu'il me manquait. Je comprends mieux pourquoi l'erreur n'est pas détectée puisque que le code n'est pas exécuté. Le comportement est donc normal.
    UNE REPONSE UTILE : &|| UN PROBLEME RESOLU :

  8. #8
    Membre confirmé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Points : 460
    Points
    460
    Par défaut
    Pour information, j'ai testé sur PS 2.0 votre suggestion:

    Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $l = @( $false, $false, $false )
    $c = @($l) | Where { $_ -eq $true )
    @($c).Count

    Cela renvoie 1 et non 0. Le seul moyen est de tester si la liste vaut $null et sinon on peut faire le count.

    J'ai repris le code, si vous avez des suggestions pour que ça soit plus propre/professionnel, je suis preneur.
    EDIT : je ne sais pas pourquoi l'indentation est à ce point flinguée avec le copié/collé depuis P-ISE.

    Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
     
    ##### VARIABLES  ########
     
    $Dir_SrcPath  = $args[0]
    $Dir_DstPath  = $args[1]
    $FileList_Raw = $args[2]
     
    ##### FONCTIONS ########
     
    Function Write-Log ( [Parameter(Mandatory=$False)][ValidateSet(1,2,3,4)][String]$level = 1, [Parameter(Mandatory=$True)][string]$data )
    {
        #LEVEL 1 = INFORMATION
        #LEVEL 2 = ATTENTION
        #LEVEL 3 = DEBUG
        #LEVEL 4 = ERREUR
     
        $timeStamp = (Get-Date).toString("dd/MM/yyyy - HH:mm:ss") 
        Write-Host "$timeStamp - LEVEL $level - $data"
    }
     
    Function Check-DirPath ( [Parameter(Mandatory=$True)]$path, [Parameter(Mandatory=$False)]$commentary )
    {
        $exist = Test-Path -Path $path
    	if   ( $exist ) { Write-Log -level 1 -data $( 'Le répertoire ' + $commentary + ' [' + $path + '] existe'        ) } 
        else            { Write-Log -level 4 -data $( 'Le répertoire ' + $commentary + ' [' + $path + '] n''existe pas' ) }
        return $exist
    }
     
    Function Check-PreMoveItem ( [Parameter(Mandatory=$True)]$file, [Parameter(Mandatory=$True)]$Dir_DstPath )
    {
        $status = $false
     
        $Dir_SrcPath  = $file.Directory
        $File_SrcPath = $file.FullName
        $File_DstPath = Join-Path $Dir_DstPath $file.Name
     
        $SrcExist = Test-Path -Path $File_SrcPath
        $DstExist = Test-Path -Path $File_DstPath
     
        if ( !$SrcExist                 ) { Write-Log -level 4 -data $( 'Le fichier source [' + $File_SrcPath + '] n''existe pas dans le repertoire source ['    + $Dir_SrcPath + ']' ) }
        if (  $DstExist                 ) { Write-Log -level 4 -data $( 'Le fichier source [' + $File_SrcPath + '] existe déjà dans le répertoire destination [' + $Dir_DstPath + ']' ) }
        if (  $SrcExist -and !$DstExist ) { $status = $true }
     
        return $status
    }
     
    Function Check-PostMoveItem ( [Parameter(Mandatory=$True)]$file, [Parameter(Mandatory=$True)]$Dir_DstPath )
    {
        $status = $false
     
        $Dir_SrcPath  = $file.Directory
        $File_SrcPath = $file.FullName
        $File_DstPath = Join-Path $Dir_DstPath $file.Name
     
        $SrcExist = Test-Path -Path $File_SrcPath
        $DstExist = Test-Path -Path $File_DstPath
     
        if (  $SrcExist                 ) { Write-Log -level 4 -data $( 'Le fichier source [' + $File_SrcPath + '] existe toujours dans le repertoire source ['     + $Dir_SrcPath + ']' ) }
        if ( !$DstExist                 ) { Write-Log -level 4 -data $( 'Le fichier source [' + $File_SrcPath + '] n''existe pas  dans le répertoire destination [' + $Dir_DstPath + ']' ) }
        if ( !$SrcExist -and $DstExist  ) { $status = $true }
     
        return $status
    }
     
    Function Get-FileList ( [Parameter(Mandatory=$True)]$fileList )
    {
        $list = @()
        if ( ( $fileList -eq '*' ) -or ( $fileList -match '`*.' ) )
    	{
            $path = Join-Path $Dir_SrcPath $fileList
            Write-Log -level 1 -data $( 'Chemin canonique : [' + $path + ']' )
    		$list = Get-ChildItem -Path $path | Where { !$_.PSIsContainer }
    	}
    	else { $list += $FileList }
        return $list
    }
     
    Function Move-ItemAsArchive ( $file, $Dir_DstPath )
    {
        $status = Check-PreMoveItem -file $file -Dir_DstPath $Dir_DstPath
        if ( $status )
    	{
    		Move-item $($file.FullName) -Destination $Dir_DstPath
     
            $status = Check-PostMoveItem -file $file -Dir_DstPath $Dir_DstPath    
    	}
        return $status
    }
     
    Function Archive
    {
        $status      = $false ; # Variable qui détermine le bon déroulement ou non de la fonction
        $StatusList  = @()    ; # Variable qui recense le status des différentes opérations durant la fonction pour déterminer son status final
    	$FileList    = @()    ; # Initialisation de la variable qui va contenir la liste des fichiers présents dans le répertoire source
        $FileCount   = 0      ; # Variable qui compte le nombre de fichiers présents dans le répertoire source
     
        $SrcPathExist = Check-DirPath -path $Dir_SrcPath -commentary "source"
        $DstPathExist = Check-DirPath -path $Dir_DstPath -commentary "destination"
     
        if ( $SrcPathExist -and $DstPathExist )
        {
            $FileList = Get-FileList -FileList $FileList_Raw
     
    	    if ( $FileList )
    	    {
                $FileCount = @($FileList).Count
                Write-Log -level 1 -data $( '[' + $FileCount + '] fichier(s) répondant au(x) critère(s) [' + $FileList_Raw + '] sont présent(s) dans le répertoire source [' + $Dir_SrcPath + ']' )
     
                $index = 0 ; 
    		    foreach ( $f in $FileList )
    		    { 
    			    $StatusList += Move-ItemAsArchive -file $f -Dir_DstPath $Dir_DstPath
     
                    if   ( $StatusList[$index] ) { Write-Log -level 1 -data $( 'Déplacement [' + $($index+1) + '/' + $FileCount + '] du fichier [' + $f.FullName + '] vers [' + $Dir_DstPath + '] < OK>'  ) }
                    else                         { Write-Log -level 4 -data $( 'Déplacement [' + $($index+1) + '/' + $FileCount + '] du fichier [' + $f.FullName + '] vers [' + $Dir_DstPath + '] <NOK>' ) }
     
                    $index++
    		    }
    	    }
    	    else { if ( !$($Error.Count) ) {  Write-Log -level 3 -data $( 'Aucun fichier répondant au(x) critère(s) [' + $FileList_Raw + '] n''est présent dans le répertoire ' + $Dir_SrcPath ) } }          
        }
        else { $StatusList += $false } 
     
        $ErrorExist = $StatusList -contains $false
        if ( $ErrorExist ) 
        { 
            $ErrorCount = ( @($StatusList) | Where { $_ -eq $false } ).Count
            Write-Log -level 4 -data $( 'Erreur(s) de déplacement constatée(s) : [' + $ErrorCount + ']' ) 
        }
        else 
        {
            $status = $true
            if ( !$FileList ) { Write-Log -level 1 -data $( 'Aucune erreur de déplacement n''a été constatée' ) }
        }
     
        return $status 
    }
     
    Function Main
    {
        $r = @(1,1)
     
        if ( ( Archive          ) { $r[0] = 0 }
        if (  !$Error.Count  ) { $r[1] = 0 }
        else                        { Write-Log -level 4 -data $( 'Des erreurs inattendues ont été constatées ( Voir la log d''erreur pour plus de détails )' ) }
     
        return $( $r[0] + $r[1] )
    }
     
    ##### MAIN #############
     
    $MinPSVersion = 2
     
    $CR = 1
    $Error.Clear | Out-Null
     
    if   ( $($PSVersionTable.PSVersion.Major) -ge $MinPSVersion ) { $CR = Main }
    else                                                          { Write-Log -level 4 -data $( 'La version minimale requise de PS pour éxecuter ce script est la version ' + $MinPSVersion + ' contre ' + $($PSVersionTable.PSVersion.Major) + ' actuellement' ) }
     
    Exit $CR
    UNE REPONSE UTILE : &|| UN PROBLEME RESOLU :

  9. #9
    Expert confirmé

    Homme Profil pro
    Responsable déploiement (SCCM, InTune, GPO)
    Inscrit en
    Juillet 2014
    Messages
    3 184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Responsable déploiement (SCCM, InTune, GPO)
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2014
    Messages : 3 184
    Points : 5 755
    Points
    5 755
    Par défaut
    J'ai survolé ton code voici quelques propositions :
    - Syntaxe à la c# que je trouve plus lisible
    - Faire respirer son code
    - Typer au maximum les paramètres de fonction
    - Paramètre avec directive écrit sous la norme "param"
    - Utiliser la syntaxe "param" aussi pour les paramètres du script plutôt que $args
    - Il est recommandé de ne pas utiliser les alias pour le bien de tous
    - Nommer les paramètres transmis pour une meilleur visibilité/compréhension
    - Modification de l'écriture des type de chaine en "bla $var bli" plutôt que 'bla ' + $var + ' bli' me parait plus lisible

    - Utilisé les commandes au plus juste de ce que l'on veux. Par exemple utiliser PathType de Test-Path
    - Utiliser les bons types attendus. Par exemple Join-Path attend un type string et tu lui transmet un type System.IO.DirectoryInfo. Donc préférer DirectoryName plutot que Directory sur un objet System.IO.FileInfo

    - La directive #Requires -Version 2.0 peut être utilisée pour forcer une version directement géré par Powershell

    - Ta fonction Get-FileList des fois retourne des string[] des fois des System.IO.FileInfo[], ce n'est pas très propre
    - Ta fonction Archive utilise des variables qui ne lui sont pas transmises, ce n'est pas très propre
    - Pourquoi utiliser un tableau $StatusList et pas des simples compteurs [int]$StatusCountOk et [int]$StatusCountNok
    - Mettre les parenthèses si il s'agit d'une méthode $Error.Clear()
    - Utiliser -ErrorAction pour modifier le comportement d'une commande face à une erreur (me paraissait nnécessaire pour Move-item sans try/catch)
    - Utiliser try/catch pour la gestion d'erreur plus sereine et fiable, ne serais ce que pour le main histoire de ne pas louper une erreur fatale.


    Voici quelques modifications, tu verra il y en a d'autres que celles parlé ci-dessus, j'ai essayé de ne pas trop déstructuré ton code.
    PS1 : Je n'ai pas testé le code donc il y aura peut être quelques petites chose à corrigées
    PS2 : Je ne sais pas si toutes mes modifications sont compatible PS 2.0

    Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
     
    ##### VARIABLES  ########
     
    $Dir_SrcPath  = $args[0]
    $Dir_DstPath  = $args[1]
    $FileList_Raw = $args[2]
     
    ##### FONCTIONS ########
     
    Function Write-Log {
        param(
            [Parameter(Mandatory=$False)] [ValidateSet(1, 2, 3, 4)] [int]$level = 1,
            [Parameter(Mandatory=$True)] [string]$data
        )
     
        #LEVEL 1 = INFORMATION
        #LEVEL 2 = ATTENTION
        #LEVEL 3 = DEBUG
        #LEVEL 4 = ERREUR
     
        $timeStamp = (Get-Date).toString("dd/MM/yyyy - HH:mm:ss")
        Write-Host "$timeStamp - LEVEL $level - $data"
    }
     
    Function Check-DirPath
    {
        param(
            [Parameter(Mandatory=$True)] [string]$path,
            [Parameter(Mandatory=$False)] [string]$commentary
        )
     
        $exist = Test-Path -Path $path -PathType Container
     
        if ($exist)
        {
            Write-Log -level 1 -data "Le répertoire $commentary [$path] existe"
        }
        else
        {
            Write-Log -level 4 -data "Le répertoire $commentary [$path] n''existe pas"
        }
     
        return $exist
    }
     
    Function Check-PreMoveItem
    {
        param(
            [Parameter(Mandatory=$True)] [System.IO.FileInfo]$file,
            [Parameter(Mandatory=$True)] [string]$Dir_DstPath
        )
     
        $Dir_SrcPath  = $file.DirectoryName
        $File_SrcPath = $file.FullName
        $File_DstPath = Join-Path -Path $Dir_DstPath -ChildPath $file.Name
     
        $SrcExist = Test-Path -Path $File_SrcPath -PathType Leaf
        $DstExist = Test-Path -Path $File_DstPath -PathType Leaf
     
        if (!$SrcExist) { Write-Log -level 4 -data "Le fichier source [$File_SrcPath] n'existe pas dans le repertoire source [$Dir_SrcPath]" }
        if ($DstExist) { Write-Log -level 4 -data "Le fichier source [$File_SrcPath] existe déjà dans le répertoire destination [$Dir_DstPath]" }
     
        return ($SrcExist -and !$DstExist)
    }
     
    Function Check-PostMoveItem
    {
        param(
            [Parameter(Mandatory=$True)] [System.IO.FileInfo]$file,
            [Parameter(Mandatory=$True)] [string]$Dir_DstPath
        )
     
        $Dir_SrcPath  = $file.DirectoryName
        $File_SrcPath = $file.FullName
        $File_DstPath = Join-Path -Path $Dir_DstPath -ChildPath $file.Name
     
        $SrcExist = Test-Path -Path $File_SrcPath -PathType Leaf
        $DstExist = Test-Path -Path $File_DstPath -PathType Leaf
     
        if ($SrcExist) { Write-Log -level 4 -data "Le fichier source [$File_SrcPath] existe toujours dans le repertoire source [$Dir_SrcPath]" }
        if (!$DstExist) { Write-Log -level 4 -data "Le fichier source [$File_SrcPath] n'existe pas dans le répertoire destination [$Dir_DstPath]" }
     
        return (!$SrcExist -and $DstExist)
    }
     
    Function Get-FileList
    {
        param(
            [Parameter(Mandatory=$True)] [string]$Dir_SrcPath,
            [Parameter(Mandatory=$True)] [string]$fileList
        )
     
        $list = @()
        if ($fileList -eq '*' -or $fileList -match '`*.')
        {
            $path = Join-Path -Path $Dir_SrcPath -ChildPath $fileList
            Write-Log -level 1 -data "Chemin canonique : [$path]"
            $list = Get-ChildItem -Path $path | Where-Object {!$_.PSIsContainer}
        }
        else
        {
            $list += $FileList
        }
     
        return $list
    }
     
    Function Move-ItemAsArchive ([string]$file, [string]$Dir_DstPath)
    {
        $status = Check-PreMoveItem -file $file -Dir_DstPath $Dir_DstPath
        if ($status)
        {
            Move-item -LiteralPath $($file.FullName) -Destination $Dir_DstPath -ErrorAction SilentlyContinue
            $status = Check-PostMoveItem -file $file -Dir_DstPath $Dir_DstPath
        }
        return $status
    }
     
    Function Archive
    {
        $StatusList  = @()    ; # Variable qui recense le status des différentes opérations durant la fonction pour déterminer son status final
        $FileList    = @()    ; # Initialisation de la variable qui va contenir la liste des fichiers présents dans le répertoire source
        $FileCount   = 0      ; # Variable qui compte le nombre de fichiers présents dans le répertoire source
     
        $SrcPathExist = Check-DirPath -path $Dir_SrcPath -commentary "source"
        $DstPathExist = Check-DirPath -path $Dir_DstPath -commentary "destination"
     
        if ($SrcPathExist -and $DstPathExist)
        {
            $FileList = Get-FileList -Dir_SrcPath $Dir_SrcPath -FileList $FileList_Raw
     
            if ($FileList)
            {
                $FileCount = @($FileList).Count
                Write-Log -level 1 -data "[$FileCount] fichier(s) répondant au(x) critère(s) [$FileList_Raw] sont présent(s) dans le répertoire source [$Dir_SrcPath]"
     
                $index = 0
                foreach ($f in $FileList)
                { 
                    $StatusList += Move-ItemAsArchive -file $f -Dir_DstPath $Dir_DstPath
     
                    if ($StatusList[$index])
                    {
                        Write-Log -level 1 -data "Déplacement [$($index+1)/$FileCount] du fichier [$($f.FullName)] vers [$Dir_DstPath] <OK>"
                    }
                    else
                    {
                        Write-Log -level 4 -data "Déplacement [$($index+1)/$FileCount] du fichier [$($f.FullName)] vers [$Dir_DstPath] <NOK>"
                    }
     
                    $index++
                }
            }
            else
            {
                Write-Log -level 3 -data "Aucun fichier répondant au(x) critère(s) [$FileList_Raw] n'est présent dans le répertoire [$Dir_SrcPath]"
            }
        }
        else
        {
            $StatusList += $false
        }
     
        $ErrorExist = $StatusList -contains $false
        if ($ErrorExist) 
        { 
            $ErrorCount = (@($StatusList) | Where-Object {$_ -eq $false }).Count
            Write-Log -level 4 -data "Erreur(s) de déplacement constatée(s) : [$ErrorCount]"
            return $false
        }
        else 
        {
            $status = $true
            if (!$FileList)
            {
                Write-Log -level 1 -data "Aucune erreur de déplacement n'a été constatée"
            }
            return $true
        }
     
    }
     
    Function Main
    {
        $ResultArchive = Archive
     
        if ($Error.Count -gt 0)
        {
            Write-Log -level 4 -data "Des erreurs inattendues ont été constatées (voir la log d'erreur pour plus de détails)"
        }
     
        return [int]!$ResultArchive + $Error.Count
    }
     
    ##### MAIN #############
     
    $MinPSVersion = 2
    $Error.Clear()
     
    if ($PSVersionTable.PSVersion.Major -ge $MinPSVersion)
    {
        $CR = Main
    }
    else
    {
        $CR = 1
        Write-Log -level 4 -data "La version minimale requise de PS pour éxecuter ce script est la version $MinPSVersion contre $($PSVersionTable.PSVersion.Major) actuellement"
    }
     
    Exit $CR

    Edit : Effectivement l'indentation par en choucroute surement du à l'utilisation d'espace et tabulation mélangé

  10. #10
    Membre confirmé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Points : 460
    Points
    460
    Par défaut
    Super, merci pour ton temps et tes remarques =) , je vais essayer d'appliquer chacune d'entres elles ! Je manquerai pas de faire un autre retour.
    UNE REPONSE UTILE : &|| UN PROBLEME RESOLU :

  11. #11
    Membre confirmé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Points : 460
    Points
    460
    Par défaut
    J'ai modifié de la sorte, en espérant que ça ressemble plus à ce que ça devrai ressembler.
    Il me restera à modifier le comptage avec des int plutot qu'une liste

    Effectivement, y'avait bien souci ici.
    Par contre Test-Path ne peut pas déterminer s'il s'agit d'une Leaf ou Container si le chemin contient un wildward.
    Je suis obligé d'exclure ce cas avant de faire le test, je ne sais pas s'il y a une manière plus élégante de le faire.

    Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    Function Get-FileList
    {
        param(
            [Parameter(Mandatory=$True)] [string]$Dir_SrcPath,
            [Parameter(Mandatory=$True)] [string]$FileList
        )
     
        $list = @()
        $path = Join-Path -Path $Dir_SrcPath -ChildPath $FileList
     
        $IsAContainer = $false
        if ( $path -notmatch '`*' )
        {
            $IsAContainer = Test-Path -Path $path -PathType Container -eq $true
        }
     
        if ( !$IsAContainer )
        {  
            Write-Log -level 1 -data "Chemin canonique : [$path]"
            $list = Get-ChildItem -Path $path | Where-Object {!$_.PSIsContainer}
        }
        else
        {
            Write-Log -level 4 -data "Le chemin canonique [$path] pointe vers un dossier, cette opération n'est pas autorisée dans le cadre de ce script"
        }
     
        return $list
    }

    Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
     
    ##### FONCTIONS ########
     
    Function Write-Log {
        param(
            [Parameter(Mandatory=$False)] [ValidateSet(1, 2, 3, 4)] [int]$level = 1,
            [Parameter(Mandatory=$True)] [string]$data
        )
     
        #LEVEL 1 = INFORMATION
        #LEVEL 2 = ATTENTION
        #LEVEL 3 = DEBUG
        #LEVEL 4 = ERREUR
     
        $timeStamp = (Get-Date).toString("dd/MM/yyyy - HH:mm:ss")
        Write-Host "$timeStamp - LEVEL $level - $data"
    }
     
    Function Check-DirPath
    {
        param(
            [Parameter(Mandatory=$True)] [string]$path,
            [Parameter(Mandatory=$False)] [string]$commentary
        )
     
        $exist = Test-Path -Path $path -PathType Container
     
        if ($exist)
        {
            Write-Log -level 1 -data "Le répertoire $commentary [$path] existe"
        }
        else
        {
            Write-Log -level 4 -data "Le répertoire $commentary [$path] n''existe pas"
        }
     
        return $exist
    }
     
    Function Check-PreMoveItem
    {
        param(
            [Parameter(Mandatory=$True)] [System.IO.FileInfo]$file,
            [Parameter(Mandatory=$True)] [string]$Dir_DstPath
        )
     
        $Dir_SrcPath  = $file.DirectoryName
        $File_SrcPath = $file.FullName
        $File_DstPath = Join-Path -Path $Dir_DstPath -ChildPath $file.Name
     
        $SrcExist = Test-Path -Path $File_SrcPath -PathType Leaf
        $DstExist = Test-Path -Path $File_DstPath -PathType Leaf
     
        if (!$SrcExist) { Write-Log -level 4 -data "Le fichier source [$File_SrcPath] n'existe pas dans le repertoire source [$Dir_SrcPath]" }
        if ($DstExist) { Write-Log -level 4 -data "Le fichier source [$File_SrcPath] existe déjà dans le répertoire destination [$Dir_DstPath]" }
     
        return ($SrcExist -and !$DstExist)
    }
     
    Function Check-PostMoveItem
    {
        param(
            [Parameter(Mandatory=$True)] [System.IO.FileInfo]$file,
            [Parameter(Mandatory=$True)] [string]$Dir_DstPath
        )
     
        $Dir_SrcPath  = $file.DirectoryName
        $File_SrcPath = $file.FullName
        $File_DstPath = Join-Path -Path $Dir_DstPath -ChildPath $file.Name
     
        $SrcExist = Test-Path -Path $File_SrcPath -PathType Leaf
        $DstExist = Test-Path -Path $File_DstPath -PathType Leaf
     
        if ($SrcExist) { Write-Log -level 4 -data "Le fichier source [$File_SrcPath] existe toujours dans le repertoire source [$Dir_SrcPath]" }
        if (!$DstExist) { Write-Log -level 4 -data "Le fichier source [$File_SrcPath] n'existe pas dans le répertoire destination [$Dir_DstPath]" }
     
        return (!$SrcExist -and $DstExist)
    }
     
    Function Get-FileList
    {
        param(
            [Parameter(Mandatory=$True)] [string]$Dir_SrcPath,
            [Parameter(Mandatory=$True)] [string]$FileList
        )
     
        $list = @()
        $path = Join-Path -Path $Dir_SrcPath -ChildPath $FileList
     
        $IsAContainer = $false
        if ( $path -notmatch '`*' )
        {
            $IsAContainer = Test-Path -Path $path -PathType Container -eq $true
        }
     
        if ( !$IsAContainer )
        {  
            Write-Log -level 1 -data "Chemin canonique : [$path]"
            $list = Get-ChildItem -Path $path | Where-Object {!$_.PSIsContainer}
        }
        else
        {
            Write-Log -level 4 -data "Le chemin canonique [$path] pointe vers un dossier, cette opération n'est pas autorisée dans le cadre de ce script"
        }
     
        return $list
    }
     
    Function Move-ItemAsArchive
    {
        param(
            [Parameter(Mandatory=$True)] [System.IO.FileInfo]$file,
            [Parameter(Mandatory=$True)] [string]$Dir_DstPath
        )
     
        $status = Check-PreMoveItem -file $file -Dir_DstPath $Dir_DstPath
        if ($status)
        {
            Move-item -LiteralPath $($file.FullName) -Destination $Dir_DstPath -ErrorAction SilentlyContinue
            $status = Check-PostMoveItem -file $file -Dir_DstPath $Dir_DstPath
        }
        return $status
    }
     
    Function Archive
    {
        param(
            [Parameter(Mandatory=$True)] [string]$Dir_SrcPath,
            [Parameter(Mandatory=$True)] [string]$Dir_DstPath,
            [Parameter(Mandatory=$True)] [string]$FileList_Raw
        )
     
        $StatusList = @() ; # Variable qui recense le status des différentes opérations durant la fonction pour déterminer son status final
        $FileList = @()   ; # Initialisation de la variable qui va contenir la liste des fichiers présents dans le répertoire source
        $FileCount = 0    ; # Variable qui compte le nombre de fichiers présents dans le répertoire source
     
        $SrcPathExist = Check-DirPath -path $Dir_SrcPath -commentary "source"
        $DstPathExist = Check-DirPath -path $Dir_DstPath -commentary "destination"
     
        if ($SrcPathExist -and $DstPathExist)
        {
            $FileList = Get-FileList -Dir_SrcPath $Dir_SrcPath -FileList $FileList_Raw
     
            if ($FileList)
            {
                $FileCount = @($FileList).Count
                Write-Log -level 1 -data "[$FileCount] fichier(s) répondant au(x) critère(s) [$FileList_Raw] sont présent(s) dans le répertoire source [$Dir_SrcPath]"
     
                $index = 0
                foreach ($f in $FileList)
                { 
                    $StatusList += Move-ItemAsArchive -file $f -Dir_DstPath $Dir_DstPath
     
                    if ($StatusList[$index])
                    {
                        Write-Log -level 1 -data "Déplacement [$($index+1)/$FileCount] du fichier [$($f.FullName)] vers [$Dir_DstPath] <OK>"
                    }
                    else
                    {
                        Write-Log -level 4 -data "Déplacement [$($index+1)/$FileCount] du fichier [$($f.FullName)] vers [$Dir_DstPath] <NOK>"
                    }
                    $index++
                }
            }
            else
            {
                Write-Log -level 3 -data "Aucun fichier répondant au(x) critère(s) [$FileList_Raw] n'est présent dans le répertoire [$Dir_SrcPath]"
            }
        }
        else
        {
            $StatusList += $false
        }
     
        $ErrorExist = $StatusList -contains $false
        if ($ErrorExist) 
        { 
            $ErrorCount = @($StatusList | Where-Object {$_ -eq $false }).Count
            Write-Log -level 4 -data "Erreur(s) de déplacement constatée(s) : [$ErrorCount]"
            return $false
        }
        else 
        {
            Write-Log -level 1 -data "Aucune erreur de déplacement n'a été constatée"
            return $true
        }
     
    }
     
    Function Get-ArchiveResult
    {
        param(
            [Parameter(Mandatory=$True)] [string]$Dir_SrcPath,
            [Parameter(Mandatory=$True)] [string]$Dir_DstPath,
            [Parameter(Mandatory=$True)] [string]$FileList_Raw
        )
     
        $ResultArchive = Archive -Dir_SrcPath $Dir_SrcPath -Dir_DstPath $Dir_DstPath -FileList_Raw $FileList_Raw
     
        if ($Error.Count -gt 0)
        {
            Write-Log -level 4 -data "Des erreurs inattendues ont été constatées (voir la log d'erreur pour plus de détails)"
        }
     
        return [int]!$ResultArchive + $Error.Count
    }
     
    Function Main
    {
        param(
            [Parameter(Mandatory=$True)] [string]$Dir_SrcPath,
            [Parameter(Mandatory=$True)] [string]$Dir_DstPath,
            [Parameter(Mandatory=$True)] [string]$FileList_Raw
        )
     
        $MinPSVersion = 2
     
        if ( [Int32]$PSVersionTable.PSVersion.Major -ge $MinPSVersion)
        {
            if ( $args[0] -ne '' -and $args[1] -ne '' -and $args[2] -ne ''  )
            {
                $CR = Get-ArchiveResult -Dir_SrcPath $Dir_SrcPath -Dir_DstPath $Dir_DstPath -FileList_Raw $FileList_Raw
            }
            else 
            {
                $CR = 1
                Write-Log -level 4 -data "Au moins 1 des arguments passés en paramètre est une chaine vide"
            }
        }
        else
        {
            $CR = 1
            Write-Log -level 4 -data "La version minimale requise de PS pour exécuter ce script est la version $MinPSVersion contre $($PSVersionTable.PSVersion.Major) actuellement"
        }
     
        return $CR
    }
     
    ##### MAIN #############
     
    try 
    { 
        $Error.Clear()
        exit Main -Dir_SrcPath $args[0] -Dir_DstPath $args[1] -FileList_Raw $args[2]
    }
    catch 
    {
        Write-Host "Une ou plusieurs erreurs ont été constatées"
        Write-Host $Error
        exit 1
    }
    UNE REPONSE UTILE : &|| UN PROBLEME RESOLU :

  12. #12
    Expert confirmé

    Homme Profil pro
    Responsable déploiement (SCCM, InTune, GPO)
    Inscrit en
    Juillet 2014
    Messages
    3 184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Responsable déploiement (SCCM, InTune, GPO)
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2014
    Messages : 3 184
    Points : 5 755
    Points
    5 755
    Par défaut
    Comme ceci peut être
    Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    Function Get-FileList
    {
        param(
            [Parameter(Mandatory=$True)] [string]$Dir_SrcPath,
            [Parameter(Mandatory=$True)] [string]$FileList
        )
     
        $list = @()
        $path = Join-Path -Path $Dir_SrcPath -ChildPath $FileList
     
        if (Test-Path -LiteralPath $path -PathType Container)
        {
            Write-Log -level 4 -data "Le chemin canonique [$path] pointe vers un dossier, cette opération n'est pas autorisée dans le cadre de ce script"
        }
        else
        {
            Write-Log -level 1 -data "Chemin canonique : [$path]"
            $list = Get-ChildItem -Path $path | Where-Object {!$_.PSIsContainer}
        }
     
        return $list
    }
    Tu as conscience que ta fonction Get-FileList retourne une liste d'objet System.IO.FileInfo (c'est peut être voulu)

    Edit : J'ai regardé un peu plus loin, c’a à l'air voulu

  13. #13
    Expert confirmé

    Homme Profil pro
    Responsable déploiement (SCCM, InTune, GPO)
    Inscrit en
    Juillet 2014
    Messages
    3 184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Responsable déploiement (SCCM, InTune, GPO)
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2014
    Messages : 3 184
    Points : 5 755
    Points
    5 755
    Par défaut
    Il te reste aussi cela

    - Utiliser la syntaxe "param" aussi pour les paramètres du script plutôt que $args

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Débat] La gestion d'erreur avec On Error Goto
    Par Igloobel dans le forum Général VBA
    Réponses: 23
    Dernier message: 08/01/2019, 18h10
  2. Gestion erreur avec vlookup vba
    Par Cyril031 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 12/04/2017, 11h05
  3. [AC-2003] Gestion erreur avec une requete mise a jour
    Par taz devil dans le forum IHM
    Réponses: 4
    Dernier message: 06/08/2015, 14h34
  4. gestion d'erreur avec throw -> fatal error
    Par laurentSc dans le forum Langage
    Réponses: 2
    Dernier message: 01/08/2013, 19h54
  5. [Sybase ASE 12.5.3] Gestion d'erreur avec @@error
    Par lsone dans le forum Sybase
    Réponses: 5
    Dernier message: 24/07/2006, 22h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo