====== SCRIPTS ====== ---- ===== PYTHON ===== Script pour commandes multithread sur plusieurs switchs #!/usr/bin/env python3 from concurrent.futures import ThreadPoolExecutor, as_completed from datetime import datetime from getpass import getpass import threading from pathlib import Path import os import socket from netmiko import ConnectHandler SWITCH_FILE = "switches.txt" MAX_WORKERS = 20 print_lock = threading.Lock() def safe_print(*a, **kw): with print_lock: print(*a, **kw, flush=True) def load_hosts(path): p = Path(path) if not p.exists(): return [] return [x.strip() for x in p.read_text().splitlines() if x.strip()] # --------- AJOUT : TEST SSH AVANT CONNEXION ----------- def test_ssh_port(host, port=22, timeout=2): try: with socket.create_connection((host, port), timeout=timeout): return True except: return False # ------------------------------------------------------- def run_on_switch(host, username, password, commands): result = { "host": host, "success": False, "error": None, "lines": [], "start": datetime.now(), "end": None, } # --- Test SSH avant toute connexion --- if not test_ssh_port(host): result["error"] = "SSH inaccessible (port 22 fermé / host down)" result["end"] = datetime.now() return result try: device = { "device_type": "cisco_ios", "host": host, "username": username, "password": password, } conn = ConnectHandler(**device) except Exception as e: result["error"] = f"SSH ERROR : {e}" result["end"] = datetime.now() return result try: conn.send_command("terminal length 0") for cmd in commands: out = conn.send_command(cmd, read_timeout=20) for line in out.splitlines(): safe_print(f"[{host}] {line}") result["lines"].append(line) result["success"] = True except Exception as e: result["error"] = f"COMMAND ERROR : {e}" finally: conn.disconnect() result["end"] = datetime.now() return result def choose_switches(hosts): while True: safe_print("\n====== SÉLECTION DES SWITCHES ======") for i, h in enumerate(hosts, 1): safe_print(f"{i}) {h}") safe_print("\nOptions :") safe_print(" X -> numéro d’un switch") safe_print(" 1,3 -> plusieurs switchs") safe_print(" all -> tous les switches") safe_print(" back -> revenir") safe_print("====================================") choice = input("Votre sélection : ").strip().lower() if choice == "back": return None if choice == "all": return hosts try: indices = [int(x.strip()) for x in choice.split(",")] selected = [hosts[i - 1] for i in indices if 1 <= i <= len(hosts)] if selected: return selected except: pass safe_print("Sélection invalide.") def main(): hosts = load_hosts(SWITCH_FILE) if not hosts: safe_print(f"Erreur : fichier {SWITCH_FILE} introuvable ou vide.") return safe_print(f"{len(hosts)} switches chargés.") username = input("Identifiant SSH : ").strip() password = getpass("Mot de passe SSH : ") current_selection = hosts # par défaut : tous while True: safe_print("\n====== MENU PRINCIPAL ======") safe_print("Switches sélectionnés :") for h in current_selection: safe_print(f" - {h}") safe_print("\nOptions :") safe_print(" cmd -> taper des commandes") safe_print(" sel -> changer la sélection") safe_print(" clear -> effacer l'écran") safe_print(" exit -> quitter") safe_print("============================") choice = input("> ").strip().lower() if choice == "exit": return if choice == "clear": os.system("cls" if os.name == "nt" else "clear") continue if choice == "sel": new_sel = choose_switches(hosts) if new_sel: current_selection = new_sel continue if choice == "cmd": safe_print("Entrez vos commandes (ligne vide pour lancer l'exécution).") commands = [] while True: cmd = input("> ").strip() if cmd == "": if commands: break else: continue commands.append(cmd) safe_print("\n====== EXÉCUTION ======\n") start_all = datetime.now() results = [] with ThreadPoolExecutor(max_workers=min(MAX_WORKERS, len(current_selection))) as pool: future_map = { pool.submit(run_on_switch, h, username, password, commands): h for h in current_selection } for f in as_completed(future_map): results.append(f.result()) # --- Résumé synthétique --- safe_print("\n======= RÉSUMÉ =======") for r in results: host = r["host"] status = "OK" if r["success"] else "ERREUR" lines = len(r["lines"]) dur = (r["end"] - r["start"]).total_seconds() safe_print(f"- {host}: {status} | lignes: {lines} | durée: {dur:.1f}s") if r["error"]: safe_print(f" -> {r['error']}") total = (datetime.now() - start_all).total_seconds() safe_print(f"Durée totale : {total:.1f}s") safe_print("=======================\n") if __name__ == "__main__": main() ---- ===== WINDOWS ===== ---- ==== CONVERSION M4A EN FLAC AVEC FFMPEG ==== 🪟 Sur Windows (PowerShell ou CMD) : Dans le dossier contenant les .m4a exécuter : #for %a in (*.m4a) do ffmpeg -i "%a" -c:a flac -map_metadata 0 "%~na.flac" ---- === SCRIPT NMAP === #!/bin/sh #liste des hotes echo "Entrer le subnet du vlan 10/301 au format X.X.X.X/24 :" read sub # on récupère toute les ip du subnet list_ip=$(nmap -sP $sub | grep -o '[0-9]\+[.][0-9]\+[.][0-9]\+[.][0-9]\+'| grep -v '.\(\.129\|130\)$') echo "liste des ip scannées :" echo "$list_ip" ---- ==== REBOOT CARTE RESEAU CMD ==== @echo off set INTERFACE="ethernet" netsh interface set interface name=%interface% admin=disabled timeout /t 1 /nobreak >nul netsh interface set interface name=%interface% admin=enabled ---- ==== Afficher variables Windows CMD ==== set Différentes commandes: ECHO : affiche le texte des commandes exécutées à l’écran @ECHO OFF : masque le texte des commandes exécutées à l’écran START : exécute un fichier avec l’application standard REM : indique une ligne de commentaire MKDIR/RMDIR : crée ou supprime un répertoire DEL : supprime le/les fichier(s) sélectionné(s) COPY : copie le/les fichier(s) sélectionné(s) TITLE : traite le titre de la fenêtre CMD Pour break/pause ds script: timeout /nobreak /T 15 Pour opérateur: L'opérateur || appelle l'élément suivant si la commande précédente échoue (ne renvoie pas un ERRORLEVEL de 0). L'opérateur && appelle l'élément suivant si la commande précédente réussit (renvoie un ERRORLEVEL de 0). #SET "THEUSER=username" #NET USER "%THEUSER%" 1>NUL 2>&1 || NET USER "%THEUSER%" Password /ADD #net user "UserName" 1>NUL 2>&1 && net user "UserName" /delete ---- ==== Script pour vider spooler impression ==== Powershell: #Stop-Service Spooler #Remove-Item "C:\Windows\System32\spool\PRINTERS\*.*" -Force #Start-Service Spooler CMD: #net stop spooler #del /q /s C:\Windows\System32\spool\PRINTERS\* #net start spooler ---- ==== Script Powershell ajout local admin user ==== $adminName = "abcadmin" $adminPW = "password123" $securePW = $adminPW | ConvertTo-SecureString -AsPlainText -Force $adminExist = Get-LocalUser -Name $adminName -ErrorAction SilentlyContinue if ($null -eq $adminExist.Name) { New-LocalUser -Name $adminName -AccountNeverExpires -PasswordNeverExpires -Password $securePW Add-LocalGroupMember -Group "Administrators" -Member $adminName } else { Set-LocalUser -Name $adminName -AccountNeverExpires -PasswordNeverExpires $True -Password $securePW } ==== Script Powershell ajout local admin user avec MDP crypté AES ==== Solution : Chiffrement AES pour stocker le mot de passe * On génère une clé AES (256 bits) et un vecteur d’initialisation (IV). * On chiffre le mot de passe avec AES et on l’enregistre dans un fichier. * On peut ensuite le déchiffrer pour l’utiliser dans un script. - Générer une clé AES et un IV (une seule fois) Exécute cette commande pour générer une clé AES et un IV : $AESKey = New-Object Byte[] 32 # Clé 256 bits (32 octets) $AESIV = New-Object Byte[] 16 # IV 128 bits (16 octets) [Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($AESKey) [Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($AESIV) # Sauvegarde de la clé et de l'IV $AESKey | Out-File "C:\AES_Key.key" $AESIV | Out-File "C:\AES_IV.key" Write-Host "Clé AES et IV générés et stockés." La clé AES (256 bits) et l’IV (128 bits) sont stockés dans des fichiers binaires. - Chiffrer le mot de passe avec AES Ajoute ce script pour chiffrer ton mot de passe et l’enregistrer dans un fichier sécurisé : # Charger la clé AES et l'IV $AESKey = Get-Content "C:\AES_Key.key" -Encoding Byte $AESIV = Get-Content "C:\AES_IV.key" -Encoding Byte # Mot de passe à chiffrer $Password = "VotreMotDePasseSécurisé123!" $PlainBytes = [System.Text.Encoding]::UTF8.GetBytes($Password) # Chiffrement AES $AES = [System.Security.Cryptography.AesManaged]::new() $AES.Key = $AESKey $AES.IV = $AESIV $Encryptor = $AES.CreateEncryptor() $CipherBytes = $Encryptor.TransformFinalBlock($PlainBytes, 0, $PlainBytes.Length) # Stocker le mot de passe chiffré $CipherBytes | Out-File "C:\EncryptedPassword.aes" Write-Host "Mot de passe chiffré avec AES et stocké." Le mot de passe est maintenant chiffré avec AES et stocké dans un fichier .aes. - Déchiffrer le mot de passe AES dans un script Ajoute ce script pour récupérer le mot de passe : # Charger la clé AES et l'IV $AESKey = Get-Content "C:\AES_Key.key" -Encoding Byte $AESIV = Get-Content "C:\AES_IV.key" -Encoding Byte # Charger le mot de passe chiffré $CipherBytes = Get-Content "C:\EncryptedPassword.aes" -Encoding Byte # Déchiffrement AES $AES = [System.Security.Cryptography.AesManaged]::new() $AES.Key = $AESKey $AES.IV = $AESIV $Decryptor = $AES.CreateDecryptor() $PlainBytes = $Decryptor.TransformFinalBlock($CipherBytes, 0, $CipherBytes.Length) $Password = [System.Text.Encoding]::UTF8.GetString($PlainBytes) Write-Host "Mot de passe déchiffré : $Password" # Convertir en SecureString pour une utilisation sécurisée $SecurePassword = ConvertTo-SecureString -String $Password -AsPlainText -Force Le mot de passe est maintenant déchiffré et prêt à être utilisé dans ton script. !! Sécurité & Bonnes Pratiques !! * Ne partage jamais la clé AES (AES_Key.key) et l’IV (AES_IV.key). * Stocke la clé sur une clé USB sécurisée si tu veux encore plus de sécurité. * Utilise $SecurePassword au lieu de $Password pour éviter d’afficher le mot de passe en clair dans PowerShell. Version complète du script Création/Mise à jour du compte admin avec AES: # Charger la clé AES et l'IV $AESKey = Get-Content "C:\AES_Key.key" -Encoding Byte $AESIV = Get-Content "C:\AES_IV.key" -Encoding Byte # Charger le mot de passe chiffré $CipherBytes = Get-Content "C:\EncryptedPassword.aes" -Encoding Byte # Déchiffrement AES $AES = [System.Security.Cryptography.AesManaged]::new() $AES.Key = $AESKey $AES.IV = $AESIV $Decryptor = $AES.CreateDecryptor() $PlainBytes = $Decryptor.TransformFinalBlock($CipherBytes, 0, $CipherBytes.Length) $Password = [System.Text.Encoding]::UTF8.GetString($PlainBytes) # Convertir en SecureString $SecurePassword = ConvertTo-SecureString -String $Password -AsPlainText -Force # Vérifie si le groupe "Administrateurs" existe, sinon le créer $AdminGroup = Get-LocalGroup -Name "Administrateurs" -ErrorAction SilentlyContinue if (-not $AdminGroup) { Write-Host "⚠️ Le groupe 'Administrateurs' n'existe pas, création en cours..." -ForegroundColor Yellow try { New-LocalGroup -Name "Administrateurs" -Description "Groupe des administrateurs locaux" Write-Host "✅ Groupe 'Administrateurs' créé avec succès." } catch { Write-Host "❌ ERREUR : Impossible de créer le groupe 'Administrateurs'. Vérifiez vos permissions." -ForegroundColor Red exit 1 } } # Vérifie si l'utilisateur existe $UserName = "Admin" $User = Get-LocalUser -Name $UserName -ErrorAction SilentlyContinue if ($User) { # Mise à jour du mot de passe Set-LocalUser -Name $UserName -Password $SecurePassword Write-Host "🔄 Le mot de passe de '$UserName' a été mis à jour." } else { # Création de l'utilisateur New-LocalUser -Name $UserName -Password $SecurePassword -FullName "Administrateur Local" -Description "Compte administrateur local sécurisé" Add-LocalGroupMember -Group "Administrateurs" -Member $UserName Write-Host "✅ Compte '$UserName' créé et ajouté au groupe 'Administrateurs'." } ---- ==== Executer script Script Powershell par cmd ==== #PowerShell.exe -command "\\halley\logiciels$\localadmin\adminaccount.ps1" ---- ==== Script Powershell restriction policy ==== 6 modes de policy: * Restricted : Cette valeur qui est la valeur par défaut, empêche l'exécution de scripts. * AllSigned : Requiert la signature numérique par un éditeur de l'ensemble des scripts, y compris ceux que vous créez en local sur la machine. * RemoteSigned : Requiert la signature numérique par un éditeur des scripts téléchargés à partir d'internet. * Unrestricted : Exécute tous les scripts, mais vous invite à autoriser l'exécution des scripts non signés téléchargés via internet. * Bypass : Pas de blocage, ni d'avertissements, tout sera exécuté. * Undefined : Supprime la stratégie d'exécution appliquée, mais pas dans le cas où elle est définie par une stratégie de groupe. #Get-ExecutionPolicy (pour connaitre le mode actuel) #Set-ExecutionPolicy Unrestricted (pour changer de mode) ---- ==== Script Powershell pour ajout route ==== @echo off :: Vérifier si la route existe déjà route print | findstr "172.16.1.0" > nul if %errorlevel% equ 0 ( echo La route 172.16.1.0 existe déjà. ) else ( echo La route n'existe pas, ajout de la route... route add -p 172.16.1.0 mask 255.255.255.0 192.9.200.232 ) ---- ==== Copies fichiers Rocketchat ==== @echo off ::Vérifie si Rocket Chat est installé si oui copie les fichiers if exist "%APPDATA%\Rocket.Chat" goto copfil goto annulcop :copfil echo Copie du fichier config.json et Rocket.Chat.lnk echo. copy "\\192.9.200.201\logiciels$\rocket_chat\config.json" "%userprofile%\%APPDATA%\Rocket.Chat" /Y if exist "%ProgramData%\Microsoft\Windows\Start Menu\Programs\Startup\Rocket.Chat.lnk" goto annulcop copy "\\192.9.200.201\logiciels$\rocket_chat\Rocket.Chat.lnk" "%ProgramData%\Microsoft\Windows\Start Menu\Programs\Startup" /Y ::rename "C:\Users\k.laurancy\Music\uninstallerIcon.ico" "uninstallerIcon.ico.old" ::robocopy /MIR "\\192.9.200.201\Logiciels$\rocket_chat" "%userprofile%\%APPDATA%\Rocket.Chat" config.json ::robocopy /MIR "\\192.9.200.201\logiciels$\rocket_chat" "%ProgramData%\Microsoft\Windows\Start Menu\Programs\Startup" Rocket.Chat.lnk echo Copie terminee echo. goto EOF :annulcop echo Copie annulee echo. goto EOF :EOF ==== Superclean de windows ==== @echo off del %temp%\*.* /S/F/Q del %windir%\prefetch\*.pf /F/S/Q del %windir%\temp\*.* /F/S/Q del %windir%\SoftwareDistribution\Download\*.* /F/S/Q Dism.exe /online /Cleanup-Image /RestoreHealth /StartComponentCleanup /ResetBase rem control /name Microsoft.IndexingOptions sfc /scannow %SystemRoot%\System32\cmd.exe /c cleanmgr /D C /sageset:65535 & cleanmgr /D C /sagerun:65535 ---- ==== Ajout PC dans domaine avec Powershell ==== #C:\Windows\system32> Add-Computer -DomainName nom_du_domain.dom ---- ==== Reeboot serveur ==== @echo off REM Redémarrage------------------------------------- shutdown /r REM Notification par mail--------------------------- PowerShell.exe -command "E:\script\notif_mail_reboot.ps1" ==== Notif par mail en powershell (*.ps1) ==== # envoi d'un mail pour notification $Destinataires = "mail@destinataire,mail@destinatairebis" [string[]]$To = $Destinataires.Split(',') Send-MailMessage -SmtpServer IP_DU_SERVEUR_SMTP -From MAIL@EXPEDITEUR -To $To -Subject "Reboot WSUS" -Body "La commande de reboot du serveur WSUS est bien lancée" -BodyAsHtml ---- ==== BACKUP WINDOWS ==== On peut créer un script .bat avec la syntaxe suivante (source - destination) : @echo off xcopy "%userprofile%\Pictures" "z:\%username%\backup\images\" /e /y /d /c xcopy "%userprofile%\Documents" "z:\%username%\backup\Documents\" /e /y /d /c pause ---- ==== Script changement fichier hosts ==== @echo off set nom1=nom_d_hote set ip1=IP_HOTE set nom2=nom_d_hote set ip2=IP_HOTE set nom3=nom_d_hote set ip3=IP_HOTE set chem="C:\Windows\System32\drivers\etc\hosts" for /f %%i in ('findstr /c:"%nom1%" %chem%') do (exit) copy %chem% "C:\Windows\System32\drivers\etc\hosts.bak" /y attrib -r %chem% echo. >> %chem% echo. >> %chem% echo %ip1% %nom1% >> %chem% echo. >> %chem% echo %ip2% %nom2% >> %chem% echo. >> %chem% echo %ip3% %nom3% >> %chem% attrib +r %chem% @echo off ::Variables set file="\\192.9.200.201\Logiciels$" set filebu="%systemroot%\System32\drivers\etc" set filebak=%systemroot%\System32\drivers\etc\hosts.bak ::Copie fichier host a partir du reseau robocopy %file% %filebu% hosts ::Vérifie si host.bak est installé si oui le désinstalle if exist %filebak% goto uninst goto EOF :uninst del /f %filebak% :EOF ---- ==== modifier rapidement config IP ==== @echo off set carte="Ethernet" set adrfixeauto=172.16.1.27 set masqueauto=255.255.255.0 set passerelleauto=172.16.1.253 set adrfixelansav=192.168.76.10 set masquelansav=255.255.255.0 set passerellelansav=192.168.76.254 :question SET /P lan=Adressage IP 1/DCHP 2/FIXE 3/QUITTER (1/2/3)? : if %lan%==1 goto IPDHCP if %lan%==2 goto IPfixe if %lan%==3 goto Nfin goto question :IPfixe SET /P WichIP=confirmer l'adressage en IP Fixe 1/autocom ou 2/lan_sav 3/quitter ? : if %WichIP%==1 goto OKFixeauto if %WichIP%==2 goto OKFixelansav if %WichIP%==3 goto Nfin goto IPfixe :OKFixeauto netsh interface IP set address %carte% static %adrfixeauto% %masqueauto% %passerelleauto% goto Ofin :OKFixelansav netsh interface IP set address %carte% static %adrfixelansav% %masquelansav% %passerellelansav% goto Ofin :IPDHCP SET /P lan=confirmer l'adressage en IP Dynamique (O/N)? : if %lan%==o goto OKDHCP if %lan%==O goto OKDHCP if %lan%==n goto Nfin if %lan%==N goto Nfin goto IPDHCP :OKDHCP netsh interface IP set address %carte% dhcp goto Ofin :Nfin @echo Aucune modification n'a ete appliquee @echo - SET /P lan=appuyez sur [ENTREE] pour quitter goto fin :Ofin @echo La nouvelle configuration vient d'etre appliquee @echo - SET /P lan=appuyer sur [ENTREE] pour quitter goto fin :fin Pour retrouver mdp wifi avec CMD et netsh: netsh wlan show profile puis: netsh wlan export profile folder=c:\ key=clear ---- ==== Backup et archivage ==== @echo off REM Création de l'espace de travail---------------------------------------------------------- if not exist "E:\backup_glpi_grr\bp_glpi_grr\" mkdir "E:\backup_glpi_grr\bp_glpi_grr\" REM dump GLPI + GRR----------------------------------------------------------------------------- "C:\xampp\mysql\bin\mysqldump.exe" -u root glpi > E:\backup_glpi_grr\bp_glpi_grr\glpidump.sql "C:\xampp\mysql\bin\mysqldump.exe" -u root grr > E:\backup_glpi_grr\bp_glpi_grr\grrdump.sql REM backups des répertoires GLPI + GRR------------------------------------------------------------------------------------ robocopy "C:\xampp\htdocs\glpi" "E:\backup_glpi_grr\bp_glpi_grr\bprep_glpi" /XO /E /S /Z /ZB /R:5 /W:5 /TBD /NP /V /MT:16 robocopy "C:\xampp\htdocs\grr" "E:\backup_glpi_grr\bp_glpi_grr\bprep_grr" /XO /E /S /Z /ZB /R:5 /W:5 /TBD /NP /V /MT:16 REM Archivages/Horodatages + compressions des dumps et répertoires----------------------------------------------------------------------------------------------------------- "C:\Program Files\7-Zip\7z.exe" a E:\backup_glpi_grr\"backupGLPI-GRR_%DATE:~0,2%.%DATE:~3,2%.%DATE:~6,4%_%time:~0,2%h%time:~3,2%.7z" "E:\backup_glpi_grr\bp_glpi_grr\" -mtc=on REM suppression des fichiers temporaires------------------------------------------------------------------------------------------------------------------------------------- rmdir /S /Q "E:\backup_glpi_grr\bp_glpi_grr\" REM Copie de l'archive vers le lecteur réseau--------------------------------- robocopy "E:\backup_glpi_grr" \\192.9.200.240\sauvegarde\ARCHIVES_GLPI_GRR /XO /E /S /Z /ZB /R:5 /W:5 /TBD /NP /V /MT:16 ---- ==== MIGRATION STOCKAGE ==== [[https://www.sikich.com/insight/how-to-perform-file-server-migrations-using-robocopy-part-1/|ROBOCOPY]] [[https://mshub.co.uk/windows-file-server-migration-with-robocopy/?fbclid=IwAR2ehtTwvMtsD7eMFu7s5LoYo9RRLZgEQbq3GjrYBWPGnXXslRhmB9HC53c|Export share permissions]] Exécuter Robocopy: #robocopy \sourceserverShareName D:SharesShareName /e /b /copyall /PURGE /r:5 /w:5 /MT:64 /tee /log+:D:Shareslog_ShareName _%date:~-10,2%"-"%date:~7,2%"-"%date:~-4,4%.txt /v Export Share Permissions Registry Key: - 1. Execute the command below on an administrative command prompt to export share permissions from the old server: #reg export HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Shares\ shareperms.reg /y - 2. Copy and Apply on the New Server: Transfer the exported registry key file to the new server and double-click on it to apply the copied share permission values. - 3. Reboot the Server: Perform a server reboot to ensure that the applied share permissions take effect. - 4. Verify Permissions After Reboot: After the reboot, check the shared folders to confirm that all permissions have been successfully applied. Depending on your server environment, especially if there have been multiple changes to share permissions, it’s advisable to perform this task on the day of the cutover. This ensures that the most up-to-date share permissions are captured and applied to the new server, maintaining a consistent access control structure ---- ==== Forcer notifications GLPI ==== @echo off C:\xampp\php\php.exe C:\xampp\htdocs\glpi\front\cron.php --force queuednotification ---- ==== informations user ==== @echo off mode con: cols=57 lines=13 color 1F echo ************ Infos utilisateur du %date% ************ echo. REM Test de connexion Internet ping www.google.fr -n 1 -w 1000 > NUL if errorlevel 0 set web=OK if errorlevel 1 set web=KO REM recupération adresse IP for /F "tokens=2 delims=:" %%i in ('"ipconfig | findstr IPv4"') do SET ipaddr=%%i for /F "tokens=2 delims=:" %%i in ('"ipconfig /all| findstr physique"') do SET macaddr=%%i REM récupération état du pare-feu for /F "tokens=2" %%i in ('"netsh advfirewall show currentprofile state | findstr tat"') do set fwstatus=%%i REM Restitution des informations echo Identifiant de connexion : %username% echo Nom de l'ordinateur : %computername% echo Adresse IP :%ipaddr% echo Adresse MAC :%macaddr% echo Connexion Internet : %web% echo Pare-feu : %fwstatus% echo. echo ********** Appuyer sur une touche pour fermer *********** pause > NUL OU AUSSI: @echo off REM Définition du nom du jour set /a J=1%DATE:~0,2% - 100 set /a M=1%DATE:~3,2% - 100 set MO=%date:~3,2% set /a A=%DATE:~6,4% set /a N=((1461 * (%A% + 4800 + (%M% - 14) / 12)) / 4 + (367 * (%M% - 2 - 12 * ((%M% - 14) / 12))) / 12 - (3 * ((%A% + 4900 + (%M% - 14) / 12) / 100)) / 4 + %J% - 32075) %% 7 if %N%==0 set JOUR=Lundi if %N%==1 set JOUR=Mardi if %N%==2 set JOUR=Mercredi if %N%==3 set JOUR=Jeudi if %N%==4 set JOUR=Vendredi if %N%==5 set JOUR=Samedi if %N%==6 set JOUR=Dimanche if %MO%==01 set NMO=JANVIER if %MO%==02 set NMO=FEVRIER if %MO%==03 set NMO=MARS if %MO%==04 set NMO=AVRIL if %MO%==05 set NMO=MAI if %MO%==06 set NMO=JUIN if %MO%==07 set NMO=JUILLET if %MO%==08 set NMO=AOUT if %MO%==09 set NMO=SEPTEMBRE if %MO%==10 set NMO=OCTOBRE if %MO%==11 set NMO=NOVEMBRE if %MO%==12 set NMO=DECEMBRE REM Définition de l'architecture 32 ou 64 bits if "%PROCESSOR_ARCHITECTURE%"=="AMD64" set nbits=64 if not "%PROCESSOR_ARCHITECTURE%"=="AMD64" set nbits=32 REM Définition de la version de Windows ver | find /i "Microsoft" > .\Winvers.txt set /P winver= < .\Winvers.txt set winver=%winver:~27,3% if "%winver%"=="5.0" set version=2000 if "%winver%"=="5.1" set version=XP if "%winver%"=="6.0" set version=Vista if "%winver%"=="6.1" set version=7 if "%winver%"=="6.3" set version=8 if "%winver%"=="10." set version=10 REM Injection de la chaine de caractère "Adresse IPv4" dans un fichier ipv4.txt ipconfig | find /i "Adresse IPv4" > .\ipv4.txt REM Création de la variable ipv4 avec pour valeur le contenu du fichier ipv4.txt set /p ipv4= < .\ipv4.txt REM Troncage de la variable ipv4 pour ne prendre que les 30 caractères suivants le 40eme set ipv4=%ipv4:~44,30% REM Injection de la chaine de caractère "Adresse physique" dans un fichier adphy.txt ipconfig /all | find /i "Adresse physique" > .\adphy.txt REM Création de la variable adphy avec pour valeur le contenu du fichier adphy.txt set /p adphy= < .\adphy.txt REM Troncage de la variable adphy pour ne prendre que les 30 caractères suivants le 40eme set adphy=%adphy:~44,30% REM Création de la variable heure avec pour valeur une version tronquée de la variable time (suppression des secondes et centiemes) set heure=%time:~0,5% REM Affichage des résultats des différentes variables Echo ======================================================== echo Informations utilisateur echo ======================================================== echo. echo DATE : le %JOUR% %date:~0,2% %NMO% %A% il est %heure% echo. echo IDENTIFIANT DE CONNEXION : %username% echo. ECHO NOM DU DOMAINE : %userdomain% echo. echo NOM DE L'ORDINATEUR : %computername% echo. ECHO VERSION WINDOWS : Windows %version% %nbits% bits echo. Echo SERVEUR DE SESSION : %logonserver:~2% echo. echo ADRESSE IP : %ipv4% echo. echo ADRESSE MAC : %adphy% echo. Echo Merci echo. pause ---- ==== Installation FusionInventory GLPI ==== @echo off if exist "%program files%\FusionInventory-Agent\" exit "\\srvglpi\tools$\fusion.exe" /S /acceptlicense /add-firewall-exception /execmode=Service /no-httpd /server="http://172.16.55.3/xampp/htdocs/glpi/plugins/fusioninventory/" /runnow /delaytime=10 pause ---- ==== Installation agent GLPI ==== @echo off echo Desinstallation de Fusion Inventory et installation du nouveau client echo. ::Vérifie si fusion inventory est installé si oui le désinstalle if exist "%PROGRAMFILES%\FusionInventory-Agent" "%programfiles%\FusionInventory-Agent\Uninstall.exe" /S echo Desinstallation terminee echo. echo Installation Agent GLPI echo. ::Vérifie si poste en 32 ou 64 puis lance l'installation en silencieux ::Renseigner le chemin où se trouve l'executable et l'adresse du serveur GLPI le reste étant par défaut if "%PROCESSOR_ARCHITECTURE%"=="AMD64" msiexec.exe /i "\\192.9.200.201\Logiciels$\glpi_agent\x64\GLPI-Agent-1.4-x64.msi" /quiet ADD_FIREWALL_EXCEPTION=1 RUNNOW=1 SERVER='http://192.9.200.202:4343/glpi/front/inventory.php' ADD_FIREWALL_EXCEPTION=1 DEBUG=1 RUNNOW=1 TASK_FREQUENCY=daily if "%PROCESSOR_ARCHITECTURE%"=="x86" msiexec.exe /i "\\192.9.200.201\Logiciels$\glpi_agent\x64\GLPI-Agent-1.4-x86" /quiet ADD_FIREWALL_EXCEPTION=1 RUNNOW=1 SERVER='http://192.9.200.202:4343/glpi/front/inventory.php' ADD_FIREWALL_EXCEPTION=1 DEBUG=1 RUNNOW=1 TASK_FREQUENCY=daily echo Installation terminee echo. ---- ==== test conditions ==== IF %Processor_Architecture% == x86 goto x86 goto x64 :x86 start /wait msiexec.exe /i install_flash_player_11_active_x_32bit.msi /qr goto EOF :x64 start /wait msiexec.exe /i install_flash_player_11_active_x_64bit.msi /qr goto EOF :EOF :: ou --- if %PROCESSOR_ARCHITECTURE% == x86 ( goto :x86 ) else ( goto :x64 ) :x86 REM put here x86 application to execute like this example FOO.EXE executabe start "foo.exe" goto :EOF :x64 REM put here x86 application to execute like this example BAR.EXE executabe start "bar.exe" goto :EOF REM put here some common code for both architectures :EOF ---- ==== Localiser IP ==== En PS: function GeolocaliserIP { $adresseIP = Read-Host "Saisissez l'adresse IP à localiser (ou tapez 'fin' pour quitter) " if ($adresseIP -eq 'fin') { return $false } $api = "http://ip-api.com/json/$adresseIP" $resultats = Invoke-RestMethod -Method Get -Uri $api Write-Host "-------------------------------------------------------------" Write-Host "Résultats de la géolocalisation pour l'adresse IP $adresseIP :" Write-Host "Pays : $($resultats.country)" Write-Host "Région : $($resultats.regionName)" Write-Host "Ville : $($resultats.city)" Write-Host "Code Postal : $($resultats.zip)" Write-Host "Latitude : $($resultats.lat)" Write-Host "Longitude : $($resultats.lon)" Write-Host "FAI : $($resultats.isp)" Write-Host "-------------------------------------------------------------" Read-Host "Appuyez sur Entrée pour continuer" return $true } while (GeolocaliserIP) {} ---- ==== Lister infos user dans l'AD (othermailbox) ==== $OUList = @("OU=Accueil,OU=Mairie,DC=saint-aubin,DC=fr", "OU=CCAS,OU=Mairie,DC=saint-aubin,DC=fr", "OU=Citergie,OU=Mairie,DC=saint-aubin,DC=fr", "OU=Comptabilité,OU=Mairie,DC=saint-aubin,DC=fr", "OU=Elus,OU=Mairie,DC=saint-aubin,DC=fr", "OU=Etat Civil,OU=Mairie,DC=saint-aubin,DC=fr", "OU=Ludotheque,OU=Mairie,DC=saint-aubin,DC=fr", "OU=Mediatheque,OU=Mairie,DC=saint-aubin,DC=fr", "OU=Point Virgule,OU=Mairie,DC=saint-aubin,DC=fr", "OU=Régie,OU=Mairie,DC=saint-aubin,DC=fr", "OU=Secrétariat Général,OU=Mairie,DC=saint-aubin,DC=fr", "OU=Service Education,OU=Mairie,DC=saint-aubin,DC=fr", "OU=Service Informatique,OU=Mairie,DC=saint-aubin,DC=fr", "OU=Service Jeunesse,OU=Mairie,DC=saint-aubin,DC=fr", "OU=Service Juridique,OU=Mairie,DC=saint-aubin,DC=fr", "OU=Service Logistique,OU=Mairie,DC=saint-aubin,DC=fr", "OU=Service restauration,OU=Mairie,DC=saint-aubin,DC=fr", "OU=Service RH,OU=Mairie,DC=saint-aubin,DC=fr", "OU=Service Technique,OU=Mairie,DC=saint-aubin,DC=fr") $Users = Foreach($OU in $OUList){ Get-ADUser -Filter {(EmailAddress -ne "null") -and (Enabled -eq "true")} -SearchBase $OU -Properties SamAccountName,emailaddress | Select-Object SamAccountName,emailaddress } $Users | Export-CSV -Path "C:\Users\Administrateur.SAINT-AUBIN\Desktop\Users.csv" -NoTypeInformation --------------------------------------------------- $OUList = @("OU=Accueil,OU=Mairie,DC=saint-aubin,DC=fr") $Users = Foreach($OU in $OUList){ Get-ADUser -Filter * -SearchBase $OU -Properties * | select name,mail,@{n="OtherMailbox";e={$_.OtherMailbox}} } $Users | Export-CSV -Path "C:\Users\Administrateur.SAINT-AUBIN\Desktop\Users.csv" -NoTypeInformation -Encoding UTF8 ---- ==== Teamviewer portable ==== @echo off :: vérif install existante if exist "%systemdrive%\TeamViewer" goto EOF goto mkdir :: création directory :mkdir mkdir "%systemdrive%\TeamViewer" :: copy exe vers directory robocopy "\\192.9.200.201\Logiciels$\teamviewer\exe" "%systemdrive%\TeamViewer" timeout /5 /nobreak :: création du raccourci mklink "%userprofile%\desktop\teamviewer" "%systemdrive%\TeamViewer\TeamViewer.exe" :EOF ---- ---- ==== Backup bdd ==== @echo off REM Variables------------------------------------------------------------------------------------------------------- set WORKSPACE=E:\backup_glpi_grr\bp_glpi_grr\ set ARCHIHOROBKP=E:\backup_glpi_grr\"backupGLPI-GRR_%DATE:~0,2%.%DATE:~3,2%.%DATE:~6,4%_%time:~0,2%h%time:~3,2%.7z" set SOURCE=E:\backup_glpi_grr set DESTINATION=\\192.9.200.240\sauvegarde\ARCHIVES_GLPI_GRR set LOG=E:\backup_glpi_grr\log_bckp_dump\%DATE:~0,2%%DATE:~3,2%%DATE:~6,4%_%TIME:~0,2%%TIME:~3,2%.log set JOUR=5 REM Création de l'espace de travail--------------------------------------------------------------------------------- if exist "%WORKSPACE%" rmdir /S /Q "%WORKSPACE%" mkdir "%WORKSPACE%" REM dump GLPI + GRR------------------------------------------------------------------------------------------------- "C:\xampp\mysql\bin\mysqldump.exe" -u root glpi > %WORKSPACE%glpidump.sql "C:\xampp\mysql\bin\mysqldump.exe" -u root grr > %WORKSPACE%grrdump.sql REM backups des répertoires GLPI + GRR------------------------------------------------------------------------------ robocopy "C:\xampp\htdocs\glpi" "%WORKSPACE%bprep_glpi" /XO /E /S /Z /ZB /R:5 /W:5 /TBD /NP /V /MT:16 robocopy "C:\xampp\htdocs\grr" "%WORKSPACE%bprep_grr" /XO /E /S /Z /ZB /R:5 /W:5 /TBD /NP /V /MT:16 REM Archivages/Horodatages + compressions des dumps et répertoires-------------------------------------------------- "C:\Program Files\7-Zip\7z.exe" a %ARCHIHOROBKP% "E:\backup_glpi_grr\bp_glpi_grr\" -mtc=on REM suppression des fichiers temporaires---------------------------------------------------------------------------- timeout /t 1 /nobreak >nul rmdir /S /Q "%WORKSPACE%" REM Copie de l'archive vers le lecteur réseau----------------------------------------------------------------------- net use s: /delete /yes net use s: \\192.9.200.240\sauvegarde timeout /t 1 /nobreak >nul robocopy "%SOURCE%" "%DESTINATION%" /XO /E /S /Z /ZB /R:5 /W:5 /TBD /NP /V /MT:16 /PURGE /LOG:"%LOG%" REM Supression anciennes sauvegardes+logs--------------------------------------------------------------------------- forfiles -p %SOURCE% -s -m *.7z -d -%JOUR% -c "cmd /c del @FILE" forfiles -p %SOURCE%\log_bckp_dump -s -m *.txt -d -%JOUR% -c "cmd /c del @FILE" REM Notification par mail------------------------------------------------------------------------------------------- PowerShell.exe -command "E:\script\notif_mail_backup.ps1" ---- ==== Applet JAVA ==== @echo off :: Test si javaws existe avec option /q where /R "%programfiles%" javaws /q if errorlevel 1 goto fin :: Création variable .exe "javaws" FOR /F "tokens=* USEBACKQ" %%F IN (`where /R "%programfiles%" javaws /f`) DO (SET var=%%F) :: Execution applet avec javaws %var% -Xnosplash "http://192.9.200.243:9090/cityweb/applet/editDocument/editDocumentWebstart.jnlp?ext=true&wsBackgroundStart=true" %var% -Xnosplash "http://192.9.200.243:9090/cityweb/applet/print/printWebstart.jnlp?ext=true&wsBackgroundStart=true" %var% -Xnosplash "http://192.9.200.243:9090/cityweb/applet/imageScan/imageScanWebstart.jnlp?ext=true&wsBackgroundStart=true" %var% -Xnosplash "http://192.9.200.243:9090/cityweb/applet/comedecClient/comedecClientWebstart.jnlp?ext=true&wsBackgroundStart=true" :: Test si fichier exception.sites existe if exist "%userprofile%\AppData\LocalLow\Sun\Java\Deployment\security\exception.sites" goto WRITESITES goto EOF :: Incrémentation des adresses :WRITESITES del /Q "%userprofile%\AppData\LocalLow\Sun\Java\Deployment\security\exception.sites" for %%a in ( http://192.9.200.243 http://192.9.200.243:9090 https://*.cms.plateforme-cartes-agents.ingroupe.com https://agents-ctae-crd.cms.plateforme-cartes-agents.ingroupe.com/cms-fo/page/login.xhtml https://agents-ctae-crd.cms.plateforme-cartes-agents.ingroupe.com/cms-fo/page/usernamelogin.xhtml https://agents-ctae.cms.plateforme-cartes-agents.ingroupe.com/cms-fo https://asscap-agents-ctae.ants.gouv.fr https://asscap.agents-ctae-sec.ants.gouv.fr https://www.agaec.ants.gouv.fr https://www.support.cartes.ants.gouv.fr https://*.cms.plateforme cartes agents.ingroupe.com https://agents ctae.cms.plateforme cartes agents.ingroupe.com/cms fo/page/operation/index.xhtml https://www.etatcivil-communes.ants.gouv.fr/services/wscommunes https://www.etatcivil-routage.ants.gouv.fr/wsdemandeV2 ) do echo %%a >> "%userprofile%\AppData\LocalLow\Sun\Java\Deployment\security\exception.sites" goto EOF :fin echo "executable javaws introuvable, veuillez l'installer" timeout 5 exit :EOF ---- ==== SCRIPT PARTAGE PHOTO ANDROID VERS PC ==== [[https://cloud.kenny.ovh/index.php/s/b6j8856MScTKJdL|dossier cloud]] ---- ===== LINUX ====== ---- ==== COMMANDES DE BASES ==== Pour connaitre son shell: #echo $0 retour bash, zsh... Mettre shebang en première ligne dans script: En général: #!/usr/bin/bash Rendre script exécutable pour l'utilisateur actuel: #chmod u+x nom_du_script Pour executer le srcipt: #./nom_du_script Variable dans script: #!/usr/bin/bash message='coucou' echo "$message mon ami" ou: echo "${message} mon ami" Résultat: #coucou mon ami $0 est égale au nom du script lui même, ici **__$0=nom_du_script__** Pour échapper, par exemple, un $ pour vraiment l'afficher, il faut mettre \ avant => \$ Pour donner le retour d'une commande: #echo $? => 0 (vrai) ou 1 (faux) Comparaison: #'valeur_1' = 'valeur_2' exemples pour tester valeurs: #machin='truc' #test $machin = 'truct' ou équivalent #[ $machin = 'truct' ] ou #echo `test $machin = 'truct'` ---- ==== CONVERSION M4A EN FLAC AVEC FFMPEG ==== Dans le dossier contenant les .m4a, exécuter : 🐧 Sur Linux (terminal bash) : #for f in *.m4a; do ffmpeg -i "$f" -c:a flac -map_metadata 0 "${f%.m4a}.flac"; done ---- ==== SCRIPT ET GESTION HDD BY CIRIL ==== script hdd à redimensionner voir fdisk -l ci-dessous: #disk resize utility cat <<"EOF" > /usr/local/bin/resize-disk #!/bin/bash echo '1' > /sys/class/block/sda/device/rescan parted ---pretend-input-tty /dev/sda resizepart 3 100%; partx -u /dev/sda3 pvresize /dev/sda3 lvextend -r -l +100%FREE $(ls /dev/mapper/*-root) EOF sh /usr/local/bin/resize-disk echo "Stop services to increase size disk to sdb"; systemctl stop cirilstartup cirilworkflow oracleCIRI echo '1' > /sys/class/block/sdbdevice/rescan umount /dev/sdb1 parted ---pretend-input-tty /dev/sdb resizepart 1 100% e2fsck -f /dev/sdb1 resize2fs /dev/sdb1 mount -a echo "Restart services after increase size disk to sdb"; systemctl start oracleCIRI cirilstartup cirilworkflow [root@ciril conf.d]# fdisk -l Disque /dev/sdb : 500 GiB, 536870912000 octets, 1048576000 secteurs Modèle de disque : Virtual disk Unités : secteur de 1 × 512 = 512 octets Taille de secteur (logique / physique) : 512 octets / 512 octets taille d'E/S (minimale / optimale) : 512 octets / 512 octets Type d'étiquette de disque : gpt Identifiant de disque : 4A31626D-42FB-4F6C-8893-BC1964569F61 Périphérique Début Fin Secteurs Taille Type /dev/sdb1 2048 1230847 1228800 600M Système EFI /dev/sdb2 1230848 3327999 2097152 1G Système de fichiers Linux /dev/sdb3 3328000 1048575966 1045247967 498,4G LVM Linux Disque /dev/sda : 200 GiB, 214748364800 octets, 419430400 secteurs Modèle de disque : Virtual disk Unités : secteur de 1 × 512 = 512 octets Taille de secteur (logique / physique) : 512 octets / 512 octets taille d'E/S (minimale / optimale) : 512 octets / 512 octets Type d'étiquette de disque : dos Identifiant de disque : 0xb143fc19 Périphérique Amorçage Début Fin Secteurs Taille Id Type /dev/sda1 2048 419430399 419428352 200G 83 Linux Disque /dev/mapper/rl-root : 490,57 GiB, 526745862144 octets, 1028800512 secteurs Unités : secteur de 1 × 512 = 512 octets Taille de secteur (logique / physique) : 512 octets / 512 octets taille d'E/S (minimale / optimale) : 512 octets / 512 octets Disque /dev/mapper/rl-swap : 7,84 GiB, 8417968128 octets, 16441344 secteurs Unités : secteur de 1 × 512 = 512 octets Taille de secteur (logique / physique) : 512 octets / 512 octets taille d'E/S (minimale / optimale) : 512 octets / 512 octets ---- ==== SCRIPTS IPSET ==== === Vider les règles iptables et ipset === Voici comment vider l’intégralité des règles iptables et ipset. En général, on utilise celle-ci en début de script pour ensuite créer les chaînes et règles. iptables -P INPUT ACCEPT iptables -P OUTPUT ACCEPT iptables -P FORWARD ACCEPT iptables -t filter -F iptables -t raw -F iptables -t nat -F iptables -t mangle -F ipset -F ipset -X === Autoriser que les IP Cloudflare sur le port 80,443 === Dans cet exemple, on autorise que les IP Cloudflare, pour cela on créé une chaîne cf4, puis on télécharge la liste des blocs d’IP CloudFlare en IPv4, enfin on autorise les connexions sur les ports 80, 443, 2408 pour les protocoles TCP et UDP. On répète l’opération pour l’IPv6. ipset destroy cf4 ipset create cf4 hash:net family inet for ip in $(curl https://www.cloudflare.com/ips-v4); do ipset add cf4 $ip; done iptables -A INPUT -m set --match-set cf4 src -p tcp -m multiport --dports 80,443,2408 -j ACCEPT iptables -A OUTPUT -m set --match-set cf4 dst -p tcp -m multiport --sports 80,443,2408 -j ACCEPT iptables -A INPUT -m set --match-set cf4 src -p udp -m multiport --dports 443 -j ACCEPT iptables -A OUTPUT -m set --match-set cf4 dst -p udp -m multiport --sports 443 -j ACCEPT ipset destroy cf6 ipset create cf6 hash:net family inet6 for ip in `curl https://www.cloudflare.com/ips-v6`; do ipset add cf6 $ip ; done ip6tables -A INPUT -m set --match-set cf6 src -p tcp -m multiport --dports 80,443 -j ACCEPT ip6tables -A OUTPUT -m set --match-set cf6 dst -p tcp -m multiport --sports 80,443 -j ACCEPT ip6tables -A INPUT -m set --match-set cf6 src -p udp -m multiport --dports 443 -j ACCEPT ip6tables -A OUTPUT -m set --match-set cf6 dst -p udp -m multiport --sports 443 -j ACCEPT === Ajouter plusieurs routeurs pour faire du masquerade === Dans cette exemples, on créé un jeu routed_nets avec la liste des routeurs. Puis on créé une règle iptables afin de faire du masquerade dessus. ipset -N routed_nets nethash ipset -A routed_nets 10.30.30.0/24 ipset -A routed_nets 10.40.40.0/24 ipset -A routed_nets 192.168.4.0/23 ipset -A routed_nets 172.22.0.0/22 iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -m set ! --set routed_nets dst -j MASQUERADE === Bloquer TOR avec ipset === On créé une chaîne tor et on bloque les connexions entrantes sur celle-ci. /usr/sbin/ipset -N tor iphash --hashsize 4096 --probes 2 --resize 50 /sbin/iptables -I INPUT -m set --match-set tor src -j DROP Puis utilisez ce script suivant qui télécharge la liste d’IP tor dans ipset. #!/bin/sh #curl -s https://check.torproject.org/exit-addresses| grep -i ExitAddress | cut -f 2 -d ' ' > /tmp/tor.txt curl -L -s https://www.dan.me.uk/torlist/|egrep "([0-9]{1,3}\.){3}[0-9]{1,3}" > /tmp/tor.txt /usr/sbin/ipset list tor|egrep "([0-9]{1,3}\.){3}[0-9]{1,3}" |sort -n> /tmp/toripset.txt lignes=$(wc -l /tmp/tor.txt) echo "il y $lignes IPs dans /tmp/tor.txt" j=0 for ip in `cat /tmp/tor.txt` do if [[ ! `egrep $ip /tmp/toripset.txt` ]] then j=`expr $j + 1` /usr/sbin/ipset add tor $ip fi done echo "$j nouvelle IPs" j=0 for ip in `cat /tmp/toripset.txt` do if [[ ! `egrep $ip /tmp/tor.txt` ]] then /usr/sbin/ipset del tor $ip j=`expr $j + 1` fi done echo "$j IPs retirees" rm -f /tmp/tor*txt ---- ==== MYSQL DATABASE BACKUP ==== [[https://www.tecmint.com/bash-script-for-mysql-backup/|tecmint]] === Step 1: Creating MySQL Backup Script === First, let’s create a simple Bash script that will handle the backup process. nano backup_mysql.sh Copy and paste the following script into the backup_mysql.sh file: #!/bin/bash # MySQL Credentials MYSQL_USER="your_mysql_username" MYSQL_PASS="your_mysql_password" MYSQL_HOST="localhost" # Backup Directory (ensure this directory exists) BACKUP_DIR="/path/to/your/backup/directory" # Email settings EMAIL_TO="you@example.com" EMAIL_SUBJECT="MySQL Backup Report - $(date +"%Y-%m-%d %H:%M:%S")" EMAIL_BODY="" # Get current date to append to backup filename DATE=$(date +"%Y-%m-%d_%H-%M-%S") # Databases to back up (list the names of the databases you want to back up) DATABASES=("db1" "db2" "db3") # Loop through each database and back it up for DB in "${DATABASES[@]}"; do BACKUP_FILE="$BACKUP_DIR/$DB_$DATE.sql" echo "Backing up database $DB to $BACKUP_FILE..." # Perform the backup using mysqldump mysqldump -u $MYSQL_USER -p$MYSQL_PASS -h $MYSQL_HOST $DB > $BACKUP_FILE # Check if the backup was successful if [ $? -eq 0 ]; then echo "Backup of $DB completed successfully!" else echo "Backup of $DB failed!" fi done # Clean up backups older than 30 days (optional) find $BACKUP_DIR -type f -name "*.sql" -mtime +30 -exec rm -f {} \; # Send email alert echo -e "$EMAIL_BODY" | mail -s "$EMAIL_SUBJECT" "$EMAIL_TO" What Does This Script Do? * MySQL Credentials: You need to provide your MySQL username, password, and host (usually localhost). * Backup Directory: This is where your backups will be stored. Make sure this directory exists on your system. * Timestamped Backup: The script creates backups with a timestamp (e.g., 2025-04-28_12-30-00.sql) to avoid overwriting old backups. * Databases to Back Up: In the DATABASES array, list the names of the databases you want to back up. You can add or remove databases as needed. * Backup Command: The script uses mysqldump to create backups of your databases. * Old Backup Cleanup: The script also deletes backups older than 30 days (you can adjust this time as needed). * Email Alerts: After running the backup, the script sends an email with the results – whether each database backup succeeded or failed. **//Sync Backup to Remote Server (Optional but Recommended)//** After your local backup is created, it’s a smart move to sync it to a remote server for extra safety, which ensures your backups survive even if your main server crashes. Here’s the rsync command you can add to the end of your backup script: # Sync backup to remote server (optional but recommended) SSH_KEY="/path/to/your/private/key.pem" # Path to your SSH private key REMOTE_USER="your_remote_user" # Remote server username REMOTE_HOST="your.remote.server.com" # Remote server address REMOTE_DIR="/path/on/remote/server" # Target directory on remote server rsync -avz \ -e "ssh -i $SSH_KEY -o StrictHostKeyChecking=no" \ --delete-after \ "$BACKUP_DIR/" \ "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/" Make sure the remote server is reachable, and the destination directory exists with proper write permissions. Once you’ve saved your script, make it executable by running chmod command: chmod +x backup_mysql.sh === Step 2: Testing MySQL Backup Script === Before setting up the Cron job, it’s a good idea to test the script manually to make sure everything is working as expected. ./backup_mysql.sh Check your backup directory to ensure the backups are created successfully. If everything looks good, proceed to the next step. === Step 3: Automating MySQL Backups with Cron Jobs === Now that we have the backup script, the next step is to automate it by using Cron, a tool that runs commands at scheduled times. crontab -e Add a Cron job to run the backup script automatically. For example, to run the script every day at 2 AM, add the following line: 0 2 * * * /bin/bash /path/to/your/backup_mysql.sh Here’s how the Cron schedule works: * 0: The minute (0th minute). * 2: The hour (2 AM). * *: Every day of the month. * *: Every month. * *: Every day of the week. To verify that your Cron job is running, you can check the system logs or temporarily set the script to run at a closer time to see if it works. grep CRON /var/log/syslog **//Additional Considerations//** * Security: Storing your MySQL password in the script is convenient but not secure. For better security, you can store your credentials in a .my.cnf file in your home directory and configure the script to read from there. * Backup Location: Make sure that the backup directory has enough space for your backups. If you’re running multiple backups, it’s a good idea to set up a separate storage location (like an external hard drive or cloud storage). * Backup Frequency: Depending on how often your data changes, you might want to adjust the Cron job schedule. For example, you could run the backup every hour, every week, or only on certain days.