{"id":55,"date":"2024-04-20T15:20:12","date_gmt":"2024-04-20T13:20:12","guid":{"rendered":"https:\/\/kev-it.fr\/?p=55"},"modified":"2024-04-22T20:40:55","modified_gmt":"2024-04-22T18:40:55","slug":"accelerez-vos-scripts-powershell-avec-les-hashtable","status":"publish","type":"post","link":"https:\/\/kev-it.fr\/index.php\/2024\/04\/20\/accelerez-vos-scripts-powershell-avec-les-hashtable\/","title":{"rendered":"Acc\u00e9lerez vos scripts PowerShell avec les HashTable"},"content":{"rendered":"\n<p>Qui n&rsquo;a jamais eu \u00e0 consolider deux listes en PowerShell ? Et comme moi, vous en avez marre de prendre un caf\u00e9 en attendant la fin du script &#8230; Et bien, je vais vous donner une petite astuce pour acc\u00e9l\u00e9rer drastiquement vos temps d&rsquo;ex\u00e9cution \ud83d\ude42<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">HashTable &#8230; kesako ?<\/h2>\n\n\n\n<p>Alors non, ce n&rsquo;est pas une technique ancestrale pour d\u00e9couper des tables. Je ne suis pas un bucheron, mais si je suis parfois un peu bourrin \ud83d\ude09 <br>Une HashTable est une liste index\u00e9e. Et c&rsquo;est l\u00e0 que tout va se jouer : sur l&rsquo;index.<\/p>\n\n\n\n<p>Prenons, un exemple : j&rsquo;ai une liste de 5000 utilisateurs avec les attributs : GUID et displayName<br>Si vous recherchez le displayName pour un GUID donn\u00e9, vous devez faire une requ\u00eate comme celle-ci<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\n$monuser = $userList |where-object {$_.GUID -eq 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'}\n<\/pre><\/div>\n\n\n<p>Le probl\u00e8me est que pour r\u00e9cup\u00e9rer la ligne qui nous int\u00e9resse, on parcours toutes les lignes une par une et on teste l&rsquo;attribut qui nous int\u00e9resse. Pas tr\u00e8s performant, vous en conviendrez.<\/p>\n\n\n\n<p>Maintenant, imaginez que nous avons construit une HashTable des utilisateurs avec le GUID comme index. Notre commande PowerShell devient<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\n$monuser = maHashTable&#x5B;'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee']\n<\/pre><\/div>\n\n\n<p>C&rsquo;est plus simple \u00e0 lire et les temps d&rsquo;ex\u00e9cution font r\u00eaver &#8230;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">La d\u00e9monstration<\/h2>\n\n\n\n<p>Dans mon exemple, je vais partir d&rsquo;une liste d&rsquo;\u00e9v\u00e8nements. Chaque \u00e9v\u00e8nement identifie un utilisateur par son GUID. De l&rsquo;autre c\u00f4t\u00e9, j&rsquo;ai la liste des utilisateurs avec le displayName associ\u00e9 au GUID.<br>Je vais cr\u00e9er les listes :<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\nfunction create-users {\n    param(\n        $count = 5000\n    )\n\n    foreach ($i in 0..$count) {\n        &#x5B;PSCustomObject]@{\n            guid = new-guid\n            displayName = &quot;Kevin-{0}&quot; -f $i\n        }\n    }\n}\n\nfunction create-events {\n    param(\n        $count=10000,\n        $guidList\n    )\n\n    foreach ($i in 0..$count) {\n        &#x5B;PSCustomObject]@{\n            id = new-guid\n            userid = $guidList |get-random\n            eventid = get-random\n        }\n    }\n}\n\n# Je g\u00e9n\u00e8re mes listes\n$users = create-users\n$events = create-events -guidList $users.guid\n<\/pre><\/div>\n\n\n<p>Maintenant, je peux parcourir mes \u00e9v\u00e8nements et associ\u00e9 le displayName \u00e0 chaque \u00e9v\u00e8nement et mesurer le temps d&rsquo;ex\u00e9cution<\/p>\n\n\n\n<p>Tout d&rsquo;abord par la m\u00e9thode habituelle<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\n$starttime1 = get-date\nforeach ($e in $events) {\n    $e|add-member -notepropertyname &quot;displayName1&quot; -notepropertyvalue ($users|? {$_.guid -eq $e.userid}).displayName -force\n}\n$duration1 = ((get-date) - $starttime1).totalseconds\n<\/pre><\/div>\n\n\n<p>Ensuite en passant par une hashtable<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\n\n# Je stocke mes utilisateurs dans une hashtable index\u00e9e par GUID\n$usersHashtable = @{}\n$users |% { $usersHashtable&#x5B;$_.guid] = $_ }\n\n# j'ajoute l'attribut displayname \u00e0 mes \u00e9v\u00e8nements par la hashtable\n$starttime2 = get-date\nforeach ($e in $events) {\n    $e|add-member -notepropertyname &quot;displayName2&quot; -notepropertyvalue $usersHashtable&#x5B;$e.userid].displayName -force\n}\n$duration2 = ((get-date) - $starttime2).totalseconds\n<\/pre><\/div>\n\n\n<p>Et maintenant je compare les r\u00e9sultats pour une liste de 5000 utilisateurs et 10000 \u00e9v\u00e8nements :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>M\u00e9thode standard : <strong>771,7362843 secondes<\/strong><\/li>\n\n\n\n<li>M\u00e9thode HashTable : <strong>6,6859321 secondes<\/strong><\/li>\n<\/ul>\n\n\n\n<p>Je pense qu&rsquo;il n&rsquo;y a pas photo \ud83d\ude42<br>Voil\u00e0, vous allez pourvoir r\u00e9duire les temps d&rsquo;ex\u00e9cution de vos scripts. Pour ceux d&rsquo;entre-vous qui font tourner des Runbook PowerShell sur Azure dans un Automation Account, vous allez faire des \u00e9conomies !!!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Qui n&rsquo;a jamais eu \u00e0 consolider deux listes en PowerShell ? Et comme moi, vous en avez marre de prendre un caf\u00e9 en attendant la fin du script &#8230; Et bien, je vais vous donner une petite astuce pour acc\u00e9l\u00e9rer drastiquement vos temps d&rsquo;ex\u00e9cution \ud83d\ude42 HashTable &#8230; kesako ? Alors non, ce n&rsquo;est pas une [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[11,8,10],"class_list":["post-55","post","type-post","status-publish","format-standard","hentry","category-dev","tag-hashtable","tag-powershell","tag-tips"],"_links":{"self":[{"href":"https:\/\/kev-it.fr\/index.php\/wp-json\/wp\/v2\/posts\/55","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kev-it.fr\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kev-it.fr\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kev-it.fr\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kev-it.fr\/index.php\/wp-json\/wp\/v2\/comments?post=55"}],"version-history":[{"count":2,"href":"https:\/\/kev-it.fr\/index.php\/wp-json\/wp\/v2\/posts\/55\/revisions"}],"predecessor-version":[{"id":70,"href":"https:\/\/kev-it.fr\/index.php\/wp-json\/wp\/v2\/posts\/55\/revisions\/70"}],"wp:attachment":[{"href":"https:\/\/kev-it.fr\/index.php\/wp-json\/wp\/v2\/media?parent=55"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kev-it.fr\/index.php\/wp-json\/wp\/v2\/categories?post=55"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kev-it.fr\/index.php\/wp-json\/wp\/v2\/tags?post=55"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}