Affichage des articles dont le libellé est Scripting. Afficher tous les articles
Affichage des articles dont le libellé est Scripting. Afficher tous les articles

jeudi 20 novembre 2014

Optimisation - Powershell

Bonjour,

Aujourd'hui je vous propose un petit article sur les différentes façons d'optimiser vos scripts powershell. Après quelques recherches sur le net je suis en effet tombé sur des solutions intéressantes.


Commençons tout de suite avec notre premier type d'optimisation : le temps d'exécution.

Performance 

Les boucles : 

En ce qui concerne les différentes possibilités de la boucle For, on retrouve classiquement le même fonctionnement que sur d'autres langages. 

Ainsi tester la condition dans la boucle comme ceci : 

$range = 1..100000            
            
For($i=0; $i -lt $range.Count; $i++) {            
    $i            
}
est 4 fois plus lent qu'en effectuant le check de l'objet range avant la boucle. (source)


For vs Foreach :

La boucle For est 40 à 50 fois plus rapide que la boucle foreach. Vous trouverez la comparaison ici.

Il est donc évident que lorsque vous avez la possibilité d'effectuer un count sur votre objet avant de faire votre boucle, si votre problématique est sur la vitesse d'exécution et non forcément la mémoire utilisée, alors l'utilisation de la boucle for est indispensable.


Utiliser -Filter : 

Il arrive fréquemment de lister quelque chose, et de filtrer notre résultat sur un nom par exemple. Et bien il existe une option sur certaines cmdlets appelé Filter. 

Celle-ci est 4 à 8 fois plus performante que le classique "$something | where{$_.name -eq "votre nom"}" puisque -Filter effectue la sélection lors de l'exécution de votre requête et ne sélectionne que les objets répondant à votre critère, là où votre Where-Object va tous les sélectionner pour ensuite rechercher ceux qui correspondent à votre chaîne. (source


Check de conditions :

Encore une fois quelque chose que l'on retrouve dans de nombreux langages. Un petit bout de code parle mieux que de longues explications : 

Code 1 : 
if(1 -eq $true)
{
   Do-Something
}

Code 2 :
if(1)
{
   Do-Something
}

Je pense que vous voyez où je veux en venir ;). (source)


Consommation mémoire

Comme la vitesse d'exécution ne fait pas tout, et qu'il est parfois nécessaire de contrôler un minimum la taille mémoire de ce que l'on récupère (notamment lors de collecte massive de données). Voici quelques petites informations que j'ai trouvé à droite et à gauche sur la toile.

Tout d'abord afin de déterminer la consommation mémoire de votre instance PowerShell : 
[System.gc]::gettotalmemory("forcefullcollection") /1MB


Pipe vs Var


Lorsque l'on récupère un ensemble d'objets grâce à une cmdlet et que l'on souhaite les retraiter par la suite, on a plusieurs possibilités.

On peut soit :
  • Stocker nos objets dans une variable et les parcourir avec un ForEach (ce qui garde tous les objets en mémoire pour la session PowerShell)
  • Passer directement nos objets un par un à notre foreach avec un pipe

Code 1 : 

$something = Get-Something
foreach($test in $something)
{
   Do-Something
}

Code 2 :

Get-Something | foreach {Do-Something}

A noter que cela répond à une situation bien précise où vous souhaitez optimiser l'utilisation mémoire plus particulièrement. En effet le code 2 sera plus soft sur la mémoire mais sera également plus lent. (source)


Sélectionner les attributs


Les objets powershell sont gros, très gros et même parfois trop gros. Il est donc nécessaire de limiter ses récupérations à certains attributs si tous ne nous intéressent pas.

Là encore on peut retrouver une commande de type "Get-Something | select anotherthing". Cela fait le travail, mais on a la possibilité de le faire de façon plus élégante avec certaines options de cmdlet (si celles-ci sont présentes car elles ne sont pas implémentées pour toutes les cmdlets.

On retrouve ainsi : -DontUseDefaultIncludedProperties et -IncludedProperties

Tout comme pour l'utilisation de -Filter, il est préférable d'utiliser ces deux options si celles-ci sont implémentées sur les cmdlets que vous utilisez puisque vous ne récupérerez alors que les attributs nécessaires et demandés et ce dès le début de votre requête (ce qui soulage votre réseau si vous requêtez du VMware ou de l'AD par exemple et accélère celle-ci). 

Je pense que leur nom est suffisamment parlant, il suffit de spécifier les propriétés que vous souhaitez récupérer après -IncludedProperties et le tour est joué. (source)


Garbage Collector


On ne peut pas parler d'optimisation mémoire sans aborder le garbage collector utilisé en PowerShell. En effet si vous vous êtes déjà intéressé à l'empreinte mémoire de vos scripts, et que vous avez cherché des solutions pour un équivalent du "Free" du C par exemple, vous avez très certainement du vous retrouver avec des réponses du genre "$var = $null".

Il se trouve que le garbage collector se charge en effet de nettoyer tous ces objets inutiles, notamment ceux présents dans vos boucles que vous ne réutiliserez plus jamais par la suite. Néanmoins, celui-ci ne passe pas forcément au bon moment et il existe donc quelques astuces pour forcer son appel.

Ainsi, le garbage collector ne passera pas lorsque vous effectuez une boucle et il attendra que celle-ci se termine, ce qui peut poser problème si vous décidez de collecter un nombre important de données dans une bonne grosse boucle de la mort (là encore je pense plus particulièrement aux personnes tapant des AD, qui récupèrent facilement de gros volumes de données).

Pour représenter un peu tout ça, j'ai effectué rapidement un bonne boucle bien sale vous faisant exploser votre mémoire : 

$a = @{}
$i = 1

while(1)
{
    $a[$i] = $i    
    $i++

}

Et si on veut appeler notre petit garbage collector dans notre boucle :  [System.GC]::Collect()

Vous pourrez tout de suite constater la différence d'évolution de la mémoire utilisée. Attention néanmoins à cette utilisation puisque appeler le garbage collector lorsque celui-ci n'est pas prévu peut faire effondrer vos performances (à utiliser donc avec précaution). (source)

Je pense avoir fait le tour de tout ce que j'ai pu trouver jusqu'à présent. Si jamais vous avez d'autres informations n'hésitez pas et partagez.

mardi 18 novembre 2014

Powershell - Getting Started

Voici un excellent scénario et tutoriel pour commencer à utiliser les principales commandes de Powershell et pouvoir évoluer par la suite : Par ici

mercredi 19 mars 2014

Script de création automatique de site web avec VirtualHost de base MySQL pour Debian

EDIT [21-03.2014] : Petite mise à jour du script.
Bonjour à tous, aujourd'hui on innove avec la publication d'un script de notre cru.

Durant mes activités d'admin système et réseau, je me suis souvent retrouvé dans le cas où je devais créer rapidement des sites web hébergés sur une Debian avec le socle LAMP.
Le truc, c'est que ça devient vite chiant quand on a pas l'habitude (surtout apache et ses virtualhost à rallonge).

Etant un poil fainéant et ne manipulant pas tous les jours apache, je me suis dit "Pourquoi ne pas avoir un script qui nous fait toutes les tâches de création pour nous?"

J'ai il y a longtemps, récupéré un script qui le faisait et je l'ai adapté pour qu'il me convienne un peu plus. Le truc c'est qu'a force de le modifier à droite à gauche il était devenue plus que sale et je me suis donc mis en demeure de le refaire depuis zéro.

C'est donc aujourd'hui le résultat de ce travail que je vous propose de découvrir.
Ce script va vous permettre de créer de manière interactive un site, lui attribuer un utilisateur et lui créer un VirtualHost et une base de données MySQL (si besoin), le tout en vous proposant le choix entre :

  • HTTP_ONLY : Le site ne répondra qu'en http,
  • HTTPS_ONLY : Le site ne répondra qu'en https,
  • HTTP_HTTPS : Le site ne répondra en http et en https,
  • HTTP_PROXY : Le site répondra en http et redirigera de façon transparente vers un autre port,
  • HTTPS_PROXY : Le site répondra en https et redirigera de façon transparente vers un autre port,
  • HTTP_HTTPS_PROXY : Le site répondra en http et https et redirigera de façon transparente vers un autre port.
Vous pourrez aussi changer le port sur lequel répondra le site et vous aurez un récapitulatif de la configuration à la fin de l'exécution du script.

Le script fonctionne sous Debian 6 et 7 avec apache2 et mysql installés depuis les dépôts.

Je vous laisse le tester et nous faire un retour dans les commentaires :)

Par contre vu que le bouzin fais dans les 450 lignes, je vous le met dans un vieux iframe bien sale depuis pastbin :p


Parmi les évolutions future :
  • automatiser la création de certificats ssl,
  • avoir une version silencieuse,
  • permettre d'avoir un site qui redirige automatiquement vers la version SSL.


PS : Pour le télécharger c'est par ici.