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 :

Mon premier script PowerShell - Gestion date fichier photo Nikon *.NEF


Sujet :

Scripts/Batch

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Ingénieur commercial
    Inscrit en
    Janvier 2022
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur commercial
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2022
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Mon premier script PowerShell - Gestion date fichier photo Nikon *.NEF
    Bonjour à tous,
    J'ai longuement cherché un logiciel pour changer les dates des fichiers photos Nikon *.NEF en utilisant la date de prise de vue qui est enregistrée dans le fichier lui-même mais je n'ai pas trouvé d'outil pour le faire en mode batch (mettre à jour un ensemble de fichiers contenus dans un répertoire avec ou sans prise en compte des sous-répertoire).
    J'ai donc décidé de faire un outil par moi-même et j'ai alors découvert le PowerShell.

    Soyez indulgent c'est mon premier script en PowerShell (je fais déjà du VBA et PowerQuery). J'ai essayé plusieurs méthodes d'accès aux fichiers et celle que j'ai retenue dans ce script (Select-String) est pour moi la plus rapide.
    J'ai appliqué ce script sur mes fichiers et il fonctionne nickel.

    Note: J'ai aussi fais un fichier LisezMoi.txt pour expliquer l'utilisation de ce script.

    Merci d'avance pour vos retours et conseils d'amélioration de ce script.
    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
    # Version released V1.0 dated January 12th, 2022
     
    # Initialisation des variables
    $Script:MyLogs = @()        # Variable journal
     
     
    # Fin de déclaration
     
    # Déclaration de sélection de dossier : Select-Folder
    function Select-Folder($message='Selectionner un répertoire', $path = 0)
    {
        $object = New-Object -comObject Shell.Application
        $folder = $object.BrowseForFolder(0, $message, 0, $path)
        if ($folder -ne $null)
        {
            $folder.self.Path
        }else
        {
            Write-Host 'Operation canceled by user'
            break
        }
    }
    # Fin de déclaration
     
    # Déclaration fonction de changementde date
    function Update-Date {
        param ([Parameter(Mandatory=$true)][Object]$MyFile, [Parameter(Mandatory=$true)][string]$MyString)
        try{
            $MyDate_creation = (Get-Date -Year $MyString.substring(0,4)`
                                        -month $MyString.substring(5,2)`
                                        -day $MyString.substring(8,2)`
                                        -hour $MyString.substring(11,2)`
                                        -minute $MyString.substring(14,2)`
                                        -second $MyString.substring(17,2)`
                                        -Millisecond 0)
            if (($MyFile.CreationTime) -eq ($MyDate_creation))
            {
                $MyDate_Creation = "NO CHANGE"
            }Else
            {
                # Change la date de création
                $MyFile.CreationTime = ($MyDate_creation)
                # Change la dernière date de modification
                $MyFile.LastWriteTime = ($MyDate_creation)
            }
            $Script:MyLogs += ,($MyFile.FullName + " ; date updated to ; " + $MyDate_creation)
        }
        catch{
            $MyStrTMP = $_.Exception.Message
            Write-Host $MyStrTMP -ForegroundColor Red
            $Script:MyLogs += ,($MyFile.FullName +  " ; ERROR ; " + $MyString.substring(15,20))
            $Script:MyLogs += ,($MyStrTMP)
        }
    }
    # Fin de déclaration
     
    Clear-Host
    # Appel de la Fonction pour afficher la boite de dialogue :
    $MyFolder=Select-Folder 'Selectionner un répertoire'
     
    # Si vous souhaitez placer le parcours de dossier sur un répertoire par défaut, il suffit d'ajouter ce paramètre :   -path "VOTRE CHEMIN"
     
    # Demande si les sous-répertoire doivent être scannés
    Do{
        $MyChoice = Read-Host -Prompt 'Do you wish to scan the sub-directories ? (Y= Yes| N= No | C = Cancel)'
    }Until(($MyChoice -eq 'C') -or ($MyChoice -eq 'Y') -or ($MyChoice -eq 'N'))
     
    # Test réponse
     
    if ($MyChoice -Eq "C")
    {
        Write-Host 'Operation canceled by user'
        break
    }elseif ($MyChoice -Eq "N")
    {
        # Sous-répertoire non inclus
        $MyList = (Get-ChildItem -Path ($MyFolder + '\*.NEF') -File)
    }elseif ($MyChoice -Eq "Y")
    {
        # Sous-répertoire inclus
        $MyList = (Get-ChildItem -Path ($MyFolder + '\*.NEF') -Recurse -File)
    }else
    {
        Write-Host 'Oups should not be there. Please contact administrator'
        # Demande de taper la touche Entrée avant de fermer la fenêtre d'éxécution
        Do{
            $MyChoice = Read-Host -Prompt "Strike Enter to close the window"
        }Until(($MyChoice -NE $null))
        break
    }
     
    # Test si le retour est vide
    if ($MyList.Length -Eq 0)
    {
        Write-Host "No NEF file found"
        $Script:MyLogs += ,"No NEF file found"
     
    }else
    {
        foreach ($MyTMP in $Mylist)
        {
            Write-Host "Processing " $MyTMP.FullName
            if ((Select-String -Path $MyTMP -Pattern "<xmp:CreateDate>").Line -match "<xmp:CreateDate>(?<content>.*)</xmp:CreateDate>" -Eq $true)
            {
                Update-Date -MyFile $MyTMP -MyString $matches['content']
            }else
            {
                Write-Host "No create date found" -ForegroundColor Red
                $Script:MyLogs += ,($MyTMP.FullName +  " ; ERROR ; " + "No create date found")
            }
        }
    }
     
    # Test si un fichier Result.txt existe déjà dans le répertoire
    if (Test-Path -path ($MyFolder + '\Result.txt'))
    {
        # Demande si le fichier existant doit être remplacé
        Do{
            $MyChoice = Read-Host -Prompt "A file Result.txt is already existing. Do you wish to replace it (Y= Yes| N= No) ? `n(If you don''t want to store the logs type C)"
        }Until(($MyChoice -eq 'C') -or ($MyChoice -eq 'Y') -or ($MyChoice -eq 'N'))
        # Test réponse
        if ($MyChoice -Eq "C")
        {
            Write-Host 'Log file not created'
            break
        }elseif ($MyChoice -Eq "N")
        {
            # Nouveaux log ajoutés au fichier existant
            $MyCurDate = get-date -format "yyyy/MM/dd HH:mm:ss" 
            ADD-content -path ($MyFolder + '\Result.txt') -value ("Log for NEF file date changing made the " + $MyCurDate)
            ADD-content -path ($MyFolder + '\Result.txt') -value $Script:MyLogs
        }elseif ($MyChoice -Eq "Y")
        {
            # Remplacement du fichier existant
            Remove-Item ($MyFolder + '\Result.txt')
            $MyCurDate = get-date -format "yyyy/MM/dd HH:mm:ss" 
            ADD-content -path ($MyFolder + '\Result.txt') -value ("Log for NEF file date changing made the " + $MyCurDate)
            ADD-content -path ($MyFolder + '\Result.txt') -value $Script:MyLogs
        }else
        {
            Write-Host 'Oups should not be there. Please contact administrator'
            break
        }
    }else
    {
        $MyCurDate = get-date -format "yyyy/MM/dd HH:mm:ss" 
        ADD-content -path ($MyFolder + '\Result.txt') -value ("Log for NEF file date changing made the " + $MyCurDate)
        ADD-content -path ($MyFolder + '\Result.txt') -value $Script:MyLogs
         # Demande de taper la touche Entrée avant de fermer la fenêtre d'éxécution
        Do{
            $MyChoice = Read-Host -Prompt "Strike Enter to close the window"
        }Until(($MyChoice -NE $null))
    }
    Write-Host '========== COMPLETED =========='
     
    Remove-Variable * -ErrorAction SilentlyContinue
    Remove-Module * -ErrorAction SilentlyContinue
    $error.Clear()
     
    #----------------END CODE--------------

    Utilisation du script PowerShell "Update NEF Photo Date.ps1" version 1.0 du 12 janvier 2022

    Important:
    L'utilisation de ce script est sous l'entière responsabilité de l'utilisateur.
    En aucune manière la responsabilité de son auteur ne pourra être retenue pour toute perte de donnée, fichier ou autre altération des photos de l'utilisateur suite à l'utilisation de ce script.
    Il est fortement recommandé de garder une copie des fichiers avant traitement par ce script et ce jusqu'à compléte vérification que les fichiers modifiés par le script sont conforme à l'attente de l'utilisateur.

    Description:
    Ce script permet de changer la date de création et de dernière écriture des fichiers photos "NEF" de Nikon.
    Il n'a pas été testé sur d'autre fichier photo.
    Les dates des fichiers sont remplacées par la date de prise de vue qui est enregistrée dans le fichier photo.

    Information importante:
    Le script utilise le PowerShell de Windows.
    Il a été développé sous Windows 10 avec la version PowerShell suivante:
    Name Value
    ---- -----
    PSVersion 5.1.19041.1320
    PSEdition Desktop
    PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
    BuildVersion 10.0.19041.1320
    CLRVersion 4.0.30319.42000
    WSManStackVersion 3.0
    PSRemotingProtocolVersion 2.3
    SerializationVersion 1.1.0.1

    L'utilisation de PowerShell peut se faire de 2 manières.
    <========== Méthode 1 ==========>
    La première consite à exécuter du code dans une interface utilisateur appelée "PowerShell ISE".
    Pour lancer cette interface, taper PowerShell dans l'invite de recherche Windows et lancer l'application "Windows PowerShell ISE".
    Pour vérifier votre version taper $PsVersionTable dans l'invite de commande (volet à fond bleu de PowerShell).

    Un volet fond blanc nommé "Sans titre1.ps1" apparait (sinon aller dans le menu Afficher et validez "Afficher le volet de script").
    Ouvrez le fichier "Update NEF Photo Date.ps1" avec le Bloc-notes et copier l'intégralité du code.
    Collez le code dans le volet "Sans titre1.ps1".
    L'éxécution du script peut se faire en cliquant sur le bouton avec une fléche verte ou en cliquant sur la touche fonction F5.

    Ensuite suivez les étapes décrites dans l'utilisation du script ci-dessous.
    <========== FIN Méthode 1 ==========>

    <========== Méthode 2 ==========>
    L'inconvénient de la méthode 1 c'est que l'on doit systématiquement lancer PowerShell ISE et copier coller le script quand on veut l'utiliser.
    Avec la méthode 2 on va directement exécuter le script "Update NEF Photo Date.ps1" avec PowerShell sans passer par la console ISE.
    Pour permettre à PowerShell d'écuter le script, il faut que les droîts soit accordé.
    En effet, PowerShell est par défaut en mode restreint pour éviter un piratage par ce biais.
    ATTENTION: Donner les droîts à PowerShell d'éxécuter un script peut être dangereux. Il est fortement recommander de revenir à la stratégie de sécurité par défaut après l'utilisation du script.

    Pour changer la stratégie d'exécution d'éxécution, il faut passer par PowerShell ISE et utiliser les lignes de commandes suivante dans la console:
    # Liste l'état actuel ==> Généralement tout est à Undefined mais ce n'est pas toujours le cas. Cherchez sur intenrnet les différentes possibilités et leurs impacts si vous n'étes pas sûr.
    Get-ExecutionPolicy -list

    # Autorise tout pour Current User ==> Sera utilisé pour autoriser l'éxécution du script
    Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser

    # Verrouille tout ==> Pour revenir à l'état antérieur après utilisation du script
    Set-ExecutionPolicy -ExecutionPolicy Undefined

    Ensuite il suffit de faire "Exécuter avec PowerShell" sur le fichier .ps1 en cliquant sur le bouton droit de la souris sur le fichier.
    <========== FIN Méthode 2 ==========>

    <========== Utilisation du script ==========>
    Au lancement le script vous demande de sélectionner un répertoire contenant les fichiers NEF a traiter.
    Une fois le répertoire sélectionné, vous devez choisir si vous voulez traiter que les fichiers du répertoire ou inclure les sous-répertoires et leur fichiers.
    Une fois le traitement terminé, un fichier "Result.txt" est disponible dans le répertoire sélectionné avec les informations sur le traitement effectué.
    Si un fichier Result.txt existe déjà le script demande si vous souhaitez le remplacer ou non. Si la réponse est non ("N"), le résultat du traitement sera ajouté à la fin du fichier. Si vous entrez "C" alors le résultat ne sera pas enregistré.
    <========== Fin utilisation du script ==========>

  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
    Bonjour,

    Un petit survole rapide.
    J'ai toujours beaucoup de chose à dire mais c'est bien pour un premier script, c'est juste histoire d'échanger

    0)
    Soyez indulgent
    Ok


    1)
    break
    Ne pas utiliser break en dehors d’une boucle, switch ou trap
    https://docs.microsoft.com/fr-fr/pow...switch-or-trap


    2)
    Test-Path
    Il est préférable de préciser ce que tu cherche avec -PathType


    3)
    Remove-Variable
    Superflue


    4)
    Remove-Module
    Tu as chargé un module ?


    5)
    $error.Clear()
    Superflue


    6)
    J'aurai préféré utiliser un objet .Net puisque PowerShell se base dessus
    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
    $null = [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")
    function Select-Folder($message = 'Selectionner un répertoire', $path = "")
    {
        $FolderBrowserDialog = New-Object System.Windows.Forms.FolderBrowserDialog
        $FolderBrowserDialog.rootfolder = [System.Environment+SpecialFolder]::MyComputer
        $FolderBrowserDialog.SelectedPath = $path
     
        if($FolderBrowserDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK)
        {
            return $FolderBrowserDialog.SelectedPath
        }
        else
        {
            Write-Host 'Operation canceled by user'
        }
    }
     
    Select-Folder


    7)
    Tu peux faire comme ceci aussi
    Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Do{
        $MyChoice = Read-Host -Prompt 'Do you wish to scan the sub-directories ? (Y= Yes| N= No | C = Cancel)'
    } Until (("C", "Y" , "N") -contains $MyChoice)


    8)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    param ([Parameter(Mandatory=$true)][System.IO.FileSystemInfo]$MyFile, [Parameter(Mandatory=$true)][string]$MyString)
    Spécifie le vrai type attendu, par un type hérité


    9)
    De manière générale, essaie de respecter la casse, la mise en forme et l’indentation que tu t'impose


    10)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [Parameter(Mandatory=$true)][string]$MyString
    Utilise des noms de paramètres parlant, MyString ne veux pas dire grande chose contrairement a MyDate


    11)
    Pour "parser" une date tu as des méthode qui existe voir : https://docs.microsoft.com/fr-fr/dot...t?view=net-6.0


    12)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $MyList = (Get-ChildItem -Path ($MyFolder + '\*.NEF') -Recurse -File)
    Les parenthèses de début et fin son superflues


    13)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ($MyList.Length -Eq 0)
    Tu peux tester facilement si quelque chose est vide ($null) comme ceci
    De plus, je pense que tu voulait utiliser Count au lieu de Length


    14)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Update-Date -MyFile $MyTMP -MyString $matches['content']
    Utilise la bonne propriété plutôt que supposer de celle qui est retourné par default
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Update-Date -MyFile $MyTMP..FullName -MyString $matches

    15)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Select-String -Path $MyTMP -Pattern "<xmp:CreateDate>"
    Lorsque le chemin est connu et déterminé je préfère l'usage de -LiteralPath au lieu de Path. Cela pourrait t'éviter certaines surprises

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Ingénieur commercial
    Inscrit en
    Janvier 2022
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur commercial
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2022
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Merci beaucoup
    Ouah!! beaucoup de piste d'amélioration. Merci pour tous ces conseils. Je vais prendre le temps de tout regarder en détail et intégrer cela dans mon code.

Discussions similaires

  1. Script Bash comparer date fichier
    Par molbento dans le forum Shell et commandes GNU
    Réponses: 2
    Dernier message: 24/08/2009, 12h12
  2. [CSV] script de gestion de fichier csv
    Par jeff74 dans le forum Langage
    Réponses: 1
    Dernier message: 06/11/2008, 11h25
  3. [AJAX] Mon premier script PHP/MYSQL/AJAX
    Par NiC1305 dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 05/04/2008, 18h51
  4. [Recherche] Script de gestion de fichiers
    Par fpouget dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 2
    Dernier message: 10/05/2006, 16h36

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