Questions et Réponses Batch, Scripts, ligne de commande

Retour à la page d'accueil Trucs et Astuces pour NT, 95, ... Boite à outils pour NT Mes amis sur le Web Liens

Q000 : Langages de Scripting  [11/2008]
Q001 : Quel éditeurs pour mes scripts  [11/2007]
Q002 : Générer un fichier daté  [11/2007]
Q003 : Sauvegarder l'état du système [11/2007]
Q004 : Utiliser une liste [01/2008]
Q005 : Utiliser un fichier du même dossier que le script lancé  [10/2008]
Q006 : Gérer les services [PS] [02/2009]
Q007 : Gérer les process [PS] [02/2009]
Q008 : Gérer les services en ligne de commande [02/2009]
Q009 : Utiliser le PowerShell dans un script .cmd [02/2009]
Q010 : Ping en PowerShell [02/2009]
Q011 : Lire ou écrire le registre en PowerShell [02/2009]
Q012 : Domaine ou Workgroup [07/2009]
Q099 : Fini pour le moment ?

Fiches orientées Scripting
O08 : Création de nouveaux Utilisateurs [10/2007]
O09 : Un exemple de Script de backup
O13 : Que se passe t'il dans mon script, présentation des mécanismes de trace [10/2007]

Par convention :

Script langage de commande (cmd.exe)
Script VBS
Script PowerShell

Retour au début de la page

Q00 : langages de scripts

mise à jours le 18/02/2009

 

PowerShell 1.0 : Module d'installation Windows PowerShell 1.0 pour Windows Vista (KB928439) [MS KB928439 ]

http://www.microsoft.com/downloads/details.aspx?FamilyID=c6ef4735-c7de-46a2-997a-ea58fdfcba63&displaylang=fr&Hash=ePDADDHvplaoHUWvNysk%2bVd7M5bedZF3KX5Ir7Md9FyCZFGJTX6YKOLPvQdpHbkqJP0gyR9DFWQnilOVdxuXzw%3d%3d

La version CTP3 (Community Technology Preview - avant les bétas) de PowerShell 2.0 est disponible (attention les CTP sont des versions de validation des fonctionnalités. Elles sont "impropres" à l'utilisation en production. Mais c'est souvent intéressant de se faire la main avec.

La CTP3 de PowerShell 2.0 peut être téléchargée via connect ou sur le site de [Microsoft ]

Pour d'autres Informations sur PowerShell voir la page Technologies Microsoft.

 

Retour au début de la page

Q01 : Quel éditeurs pour mes scripts

mise à jours le 02/11/2007

 

Pour créer un script, il n'est pas nécessaire d'avoir un outil bien compliqué, la ligne de commande peut suffire :

Copy con monscript.cmd
Echo Voila mon Script
CTRL+Z

Et voila un petit script créé pour l'occasion. Pour l'éditer facilement s'il n'est pas trop important, "Edit" existe toujours même sur les plus récents systèmes.

Voila pour les situations d'Urgence, quand on ne veux pas installer d'outils pour se faciliter la vie.

Après dans les situation courantes, on a intérêt à avoir un outil plus performant qui permet une édition efficace des scripts. C'est principalement un affaire de goût mais si vous cherchez quelques outils en voici quelques uns pour commencer :

Retour au début de la page

Q2 : Générer un fichier daté

mise à jours le 02/11/200

J'ai l'habitude de faire en sorte que mes scripts génèrent le plus souvent possible une trace de ce qui a été fait.
Comme la trace du dernier évènement n'est pas toujours suffisamment parlante ou suffisante, j'ai pris l'habitude de générer des fichiers de trace datés style :

C'est la trace d'un mailling qui a été envoyé le 21 mail 2007 (2007 05 21).

Comment obtenir l'information qui permet de dater le fichier dans un script BATCH, voila ma recette (même si vous en trouverez bien d'autres sur le net).
Voici la première version :

Rem Calcul de la chaine DATE AAAAMMJJ
set D=%DATE:/=%
set D=%D:~4,4%%D:~2,2%%D:~0,2%
Echo %D%

Très satisfaisante sur mon XP ou sur mes serveurs 2003, elle s'est révélée inadaptée sur les "vieux" serveurs 2000 parce que la commande date ne renvoie pas la date de la même façon ("lun 19/09/2006"). Donc voici la "formule" qui marche sur les XP/2003/2000 :

Rem Calcul de la chaine DATE AAAAMMJJ
set WD=%DATE:/=%
if "%WD:~4,1%"=="2" (
set D=%WD:~4,4%%WD:~2,2%%WD:~0,2%
) ELSE set D=%WD:~9,4%%WD:~7,2%%WD:~5,2%
Echo %D%

 

Retour au début de la page

Q3 : Sauvegarder l'état du système

mise à jours le 02/11/2007

Même avec l'apparition des points de restauration sous XP, j'ai pris l'habitude de faire une sauvegarde de l'état du système d'une station ou d'un serveur avant de faire une opération de mise à jours ou d'installation de logiciels.

C'est un opération facile à faire à partir de NTBACKP :Lancer NTBACKUP (éviter l'assistant), passer dans l'onglet [Sauvegarder], Cocher System State, et choisir la destination et voila :

L'autre solution qui permet aussi de planifier l'action ou de la lancer automatique sans se poser de question sur le nom du fichier, sa localisation consiste à écrire un petit script pour faire cette action.
Le script à télécharger effectue en plus du backup l'envoie d'un mail, la notification à un serveur syslog [Mettre en place un serveur SYslog Fiche-14] et la sauvegarde sur un serveur de centralisation.

@Title Sauvegarde de l'Etat du Système
@rem +----------------------------------------------------------+
@rem + Sauvegarde de l'Etat du système +
@rem + Francois Dunoyer +
@rem + cree : 06/12/2005 +
@rem + Modif : 02/11/2007 +
@rem +----------------------------------------------------------+

:: valeurs par defaut si non configurées
if "%SMTPS%"=="" Set SMTPS=smtp.Mondomaine.local
 

Set Ext=bkf
:: Par défaut définition du PC de centralisation des Sauvegardes
Set Cible=\\Poste_104
set Dossier=d$\sauvegardes\ES

:: Dans le calcul de la date, on détecte si le système est un Windows 2000 qui ne gère pas l'option cliché instantanée
:: Et on position une variable qui ajoutera cette option dans le cas des Windows 2003 ou plus

Rem Calcul de la chaine DATE AAAAMMJJ
set WD=%DATE:/=%
if "%WD:~4,1%"=="2" (
set D=%WD:~4,4%%WD:~2,2%%WD:~0,2%
set SNAPON=/snap:on
) ELSE set D=%WD:~9,4%%WD:~7,2%%WD:~5,2%

Set Message=%Action%
now %Message% >%LogBrief%

:: Voila le coeur du script, la backup de l'état du systeme

Set BackupName=%Cible%\%dossier%\%ComputerName%-ES-%D%.%Ext%
echo %Backupname%
pause
ntbackup.exe backup systemstate /n "Etat du systeme pour %ComputerName% au %DATE%" /d "ES-%ComputerName%-%D%" /F "%BackupName%" /v:no /r:no /rs:no /hc:off /m normal /j "ES-%ComputerName%-%D%" /l:f %SNAPON%

:: La c'est fini

Script complet à télécharger :

 

Retour au début de la page

Q04 : Utiliser une "liste" en batch

mise à jours le 22/01/2008

 

Comme utiliser un semblant de liste pour répéter un traitement dans une fichier de commande.

@Title Parcour d'une liste
@rem +----------------------------------------------------------+
@rem + Utilisation d'une liste
@rem + Francois Dunoyer
@rem + cree  : 22/01/2008
@rem + Modif : 22/01/2008
@rem +----------------------------------------------------------+

:: Création d'une variable

set filelist=Valeur1 Valeur2 Valeur3 Valeur4 Valeur5
set filelist=%filelist% valeur06 valeur07 Valeur08 Valeur09 valeur10
set filelist=%filelist% valeur16 valeur17 Valeur18 Valeur19 valeur20

:: Exploitation de la variable

for %%i in (%filelist%) do (
echo traitement %%i ...
traitement %%i
)

:: La c'est fini

echo.
Echo Voila c'est fini .....

 

Retour au début de la page

Q05 : Utiliser un fichier du même dossier que le script

mise à jours le 15/10/2008

 

Quand je lance manuelle un script en me positionnant dans son dossier, je n'ai pas de mal à ouvrir un fichier dans le même dossier, mais ce n'est pas toujours le cas si je clique sur un raccourci qu'il soit local ou réseau. Une petite astuce pour pouvoir accéder aux fichier de paramètre sans connaitre à l'avance le dossier dans lequel le fichier de script est stocké. j'utilise le paramètre %~dp0 qui me renvoie le dossier (d) et le chemin (d) du script en cours.

REM : j'utilise ce script pour marquer mes photos.
REM : le script et le fichier (Setcopyw.ex2) sont dans la racine du dossier, les photos dans un sous-dossier VO
REM : EXIV2 est un très bon outil pour marquer les fichiers image
REM : je n'ai qu'à cliquer sur le script pour taguer mon dossier sans me préoccuper du répertoire en cour

Exiv2 -k -m "%~dp0Setcopyw.ex2" "%~dp0vo\*.jpg"

Retour au début de la page

Q06 : Gérer les services en PowerShell

mise à jours le 18/02/2009

Pour gérer les services via le Powershell les commandes sont les suivantes ( pour s'en rappeler ? get-command *service) :

La syntaxe des commandes Restart-, Stop-, Start-,Suspend-service est similaire. Par exemple :

Pour démarrer un service :

Start-Service -displayname "planificateur de tâches"    # en utilisant le nom long
Start-Service schedule                         # en utilisant le nom court

Pour connaitre l'état d'un service :

get-wmiobject win32_service | where {$_.Name -eq "schedule"}

Pour connaitre le nom court d'un service particulier :

get-service -displayname "planificateur de tâches"

Définir le type de démarrage pour un service

set-service schedule -startuptype automatic
set-service schedule -startuptype disabled
set-service schedule -startuptype manual

 

Retour au début de la page

Q07 : Gérer les process en PowerShell

mise à jours le 18/02/2009

Pour gérer les process via le powershell les commandes sont les suivantes ( pour s'en rappeler ? get-command *process):

Pour surveiller la présence d'un process :

get-process powershell

Pour stopper une instance d'une application

stop-process -name word

Pour stopper une instance d'une application parmi n instances

PS C:\> get-process excel

Handles NPM(K) PM(K) WS(K)VM(M)CPU(s)Id ProcessName
------- ------ ----- ----- ----- ------ -- ---------
506 18 18080 36212 174 9.482384 EXCEL
459 14 14148 23288 158 1.25 5776 EXCEL

stop-process 5776

et pour les scripteurs fous qui lancent trop de shell powershell, voici comment arrêter toutes les instances de PowerShell sauf celle où la commande est lancée [Issu du blog de l'équipe PowerShell : blogs.msdn.com/powershell ]

Get-Process Powershell  | Where-Object { $_.ID -ne $pid } | Stop-Process

Retour au début de la page

Q08 : Gérer les services en ligne de commande

mise à jours le 17/02/2009

 

La commande SC

Fonctionnement de la commande SC (commande intégrée 2000/2003/XP...) : Cette commande permet d'interagir avec les services de l'ordinateur local ou même d'un ordinateur distant (sous réserve d'avoir les droits nécessaires et attention aux pare-feux).

Voici quelques exemples d'utilisation de la commande :

Trouver le nom court d'un service

Pour certaines actions il est nécessaire de connaître le « nom court » d’un service, ce « nom court » n’est hélas pas celui qui est affiché dans la console de gestion des services. Pour l’identifier, il suffit de lancer la commande :

SC GETKEYNAME « Nom Long du service »

Par exemple, pour identifier le nom court du service « Workstation Manager » :

SC Getkeyname "Workstation Manger"

[SC] GetServiceKeyName SUCCESS Name = ZFDWM

Changer le compte ou le mot de passe utilisé pour lancer un service

Identifier le nom court du service sur lequel vous voulez intervenir (cf plus haut).

La commande qui va être utilisée pour changer le compte est aussi la commande SC. Pour associer un compte à un service, il suffit de lancer la commande :

SC CONFIG NomCourtDuService obj= Compte password= MotDePasse

Attention : Il y'a un espace obligatoire entre " obj= " et le compte et entre " Password= " et le mot de passe.
Selon le compte utilisé la syntaxe sera légèrement différente.

Utilisation d'un compte local à la machine

SC config messenger obj= .\toto password= titi

Utilisation d'un compte d'un domaine AD (DOMAINEAD)

SC config messenger obj= DOMAINEAD\toto password=titi

Utilisation du compte " SYSTEM " (tous Windows)

SC config messenger obj= LocalSystem password= ""

Utilisation d'un compte intégré de moindre priorité (Windows 2003 et plus)

SC config messenger obj= "NT Authority\LocalService" password= ""
SC config messenger obj= "NT Authority\NetworkService" password= ""

Retour au début de la page

Q09 : Utiliser le PowerShell dans un script .cmd

mise à jours le 18/02/2009

Il peut être intéressant d'utiliser les possibilités du PowerShell pour enrichir ou améliorer un batch existant (en attendant de le re écrire en PowerShell par exemple :) ). Pour cela, il suffit d'appeler l'interpréteur PowerShell dans le script et de lui passer en paramètre la commande à exécuter :

PowerShell -command get-command

Si la commande est un peu plus compliquée... avec un pipe ("|") par exemple la syntaxe se complique un peu :

PowerShell -command "&{ get-command *service | format-table}"

Retour au début de la page

Q10 : Ping en PowerShell

mise à jours le 18/02/2009

Le ping est une bonne façon de savoir si un serveur ou un poste est toujours "vivant", c'est aussi une bonne façon de gagner du temps avant de lancer une commande sur un serveur distant.

Get-WmiObject -Class Win32_PingStatus -Filter "Address='127.0.0.1'"

Get-WmiObject -Class Win32_PingStatus -Filter "Address='127.0.0.1'" | Select-Object -Property Address,ResponseTime,StatusCode

Plus de détails : http://winstructor.com/articles/windows-powershell/ping.htm

Retour au début de la page

Q11 : Lire ou écrire le registre en PowerShell

mise à jours le 20/02/2009

Lecture de la version du système en cours (en version littérale)

# Lecture de la clé de registre
$value = (get-itemproperty "HKLM:\\SOFTWARE\Microsoft\Windows NT\CurrentVersion")
$Version=$Value.ProductName
$Version

Pour changer la valeur d'une clé de registre

# Changement du dossier Source pour les installations
# Il s'agit de la valeur SourcePath
Set-ItemProperty -path HKLM:\\SOFTWARE\Microsoft\Windows NT\CurrentVersion -name SourcePath -value "D:\i386"

Pour accéder au registre distant, voir : http://thepowershellguy.com/blogs/posh/archive/2007/06/20/remote-registry-access-and-creating-new-registry-values-with-powershell.aspx

Retour au début de la page

Q12 : Domaine ou Workgroup

mise à jours le 12/07/2009

 

J'ai parfois besoin de savoir dans mon script si je suis en domaine, en Workgroup et quel est ce domaine ou ce Workgroup.

Deux variables d'environnement peuvent me mettre sur la voie.

USERDOMAIN indique le nom du "domaine" d'authentification. En domaine, USERDOMAIN=NOMDOMAINE.
Si vous n'êtes pas en domaine, le "domaine" d'authentification est le PC lui même, dans ce cas USERDOMAIN=COMPUTERNAME.

Par contre en domaine, USERDOMAIN est complété par une autre variable USERDNSDOMAINE qui renvoie le nom DNS du domaine. Quelque chose du genre : mondomaine.local

Un script simple qui veut savoir s'il est en domaine peut tester :

if "%USERDOMAIN%"=="%COMPUTERNAME%" (
         Set Message=Je ne suis pas en domaine
     ) ELSE
         Set Message=je suis dans le domaine %USERDNSDOMAIN%
     )
     Echo %Message%

En VBScript, nous pouvons obtenir l'équivalent de la variable %USERDOMAIN% par la propriété UserDomain de l'objet WshNetwork. Ce qui peut donner le code suivant :

Set WshNetwork = WScript.CreateObject("WScript.Network")
WScript.Echo "Domain = " & WshNetwork.UserDomain
WScript.Echo "Computer Name = " & WshNetwork.ComputerName
WScript.Echo "User Name = " & WshNetwork.UserName

Mais ce n'est toujours pas satisfaisant si on cherche à savoir quel est le Workgroup.
Le code suivant permet de connaitre le nom du domaine (si on est en domaine) et celui du Workgroup dans le cas contraire.

set wmi = getobject("winmgmts:")
wql = "select * from win32_computersystem"
set results = wmi.execquery(wql)

For each compsys in results
    WScript.Echo "domain ou WorkGroup" & compsys.domain
Next

Retour au début de la page

Q99 : Fini ?

Pour le moment.

Script langage de commande (cmd.exe)
Script VBS
Script PowerShell

 


Le tabac nuit gravement à la santé ! Et la nicotine encrasse non seulement les poumons mais aussi les claviers et les ventilateurs ! Copyright ©1997-2009, François Dunoyer, Dernière modification le  
Recommander cette page