{"id":1612,"date":"2021-12-27T19:38:10","date_gmt":"2021-12-28T00:38:10","guid":{"rendered":"https:\/\/enterpriseadmins.org\/blog\/?p=1612"},"modified":"2021-12-27T19:38:10","modified_gmt":"2021-12-28T00:38:10","slug":"getting-started-with-saltstackconfig-powershell-module","status":"publish","type":"post","link":"https:\/\/enterpriseadmins.org\/blog\/scripting\/getting-started-with-saltstackconfig-powershell-module\/","title":{"rendered":"Getting Started with SaltStackConfig PowerShell Module"},"content":{"rendered":"\n<p>In the previous post (<a href=\"https:\/\/enterpriseadmins.org\/blog\/scripting\/getting-started-with-saltstack-config\/\">here<\/a>), we looked into Getting Started with SaltStack Config.  We created and kicked off a few tasks from the web interface.  Occasionally we&#8217;ll need to report on some data as well.  The web interface offers the ability to download many result\/output tables as CSV or JSON, but what if we wanted to do something with that data programmatically?  Fortunately there is an API available (documentation here: <a href=\"https:\/\/developer.vmware.com\/apis\/1179\/saltstack-config-raas\">https:\/\/developer.vmware.com\/apis\/1179\/saltstack-config-raas<\/a>).  Unfortunately, I couldn&#8217;t find many examples of consuming this API with PowerShell and ran into an issue as I was getting started (related to credentials).  Once I got those sorted out, I was able to create a quick inventory script that I wanted (to simply return minion names &amp; a few &#8220;grains&#8221; like the Operating System &amp; OS Version).  However, with the bit of info I picked up along the way, I decided to try and wrap things up into a PowerShell Module for future needs.  This module is available on GitHub (<a href=\"https:\/\/github.com\/vmware\/PowerCLI-Example-Scripts\/tree\/master\/Modules\/SaltStackConfig\">https:\/\/github.com\/vmware\/PowerCLI-Example-Scripts\/tree\/master\/Modules\/SaltStackConfig<\/a>) and the following post will focus on how to get started using that module.<\/p>\n\n\n\n<p>The first step to using this SaltStackConfig module is to get the required files to the system where you run scripts.  The easiest way I know to do this is to download the full project repo (there is a Code > Download ZIP button at <a href=\"https:\/\/github.com\/vmware\/PowerCLI-Example-Scripts\">https:\/\/github.com\/vmware\/PowerCLI-Example-Scripts<\/a>).  With the zip file downloaded, I like to right click and see if the &#8216;unblock&#8217; button appears in the bottom right &#8212; if so, I uncheck that (doing this prior to unzipping the file will save some time as we don&#8217;t need to recursively run Unblock-File on everything that was extracted).  <\/p>\n\n\n\n<p>I then extract the files I need, in this case the folder <code>Modules\\SaltStackConfig<\/code> and place them in one of the PowerShell Module paths (to find where these are, you can open a powershell window and type <code>$env:PSModulePath<\/code>).  <\/p>\n\n\n\n<p>With the module copied into one of the correct paths, it will load automatically the next time we start PowerShell.  Once we have that new PowerShell session, with the module now available, we can connect to the SaltStack Config environment.  This cmdlet will connect to the RaaS API and create a global variable that we can reference to use future API calls (for this PowerShell session only).<\/p>\n\n\n\n<p><code>C:\\> Connect-SscServer 'salt.example.com' -User 'root' -Password 'VMware1!'<\/code><\/p>\n\n\n\n<p>Here is the sample inventory task I was interested in that started everything:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>C:\\&gt; (Get-SscMinionCache).grains |Select-Object host, osfullname, osrelease |Sort-Object host\n\nhost             osfullname                               osrelease\n----             ----------                               ---------\ncm-vrssc-01      VMware Photon OS                         3.0\ncore-control-21  Microsoft Windows Server 2022 Standard   2022Server\ndr-control-01    Microsoft Windows Server 2016 Standard   2016Server\nraspberrypi      Raspbian                                 10\nsvcs-sql-01      Microsoft Windows Server 2016 Standard   2016Server\nt147-ubuntu-01   Ubuntu                                   20.04\nt147-ubuntu-02   Ubuntu                                   20.04\nt147-ubuntu18-01 Ubuntu                                   18.04\nt147-win22-01    Microsoft Windows Server 2022 Standard   2022Server<\/code><\/pre>\n\n\n\n<p>I liked how the osfullname property looked for Windows machines, but for the Ubuntu &amp; Photon releases I wanted to combine the osfullname and osrelease columns, so I went with a slightly modified Select-Object statement that contains some if\/else logic that pulled together the output exactly how I wanted to display it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nC:\\> (Get-SscMinionCache).grains | Select-Object host, @{Name='FriendlyOSName';Expression={ if ($_.osfullname -match 'Windows' ) { $_.osfullname } else { \"$($_.osfullName) $($_.osrelease)\"}}} | Sort-Object host\r\n\r\nhost             FriendlyOSName\r\n----             --------------\r\ncm-vrssc-01      VMware Photon OS 3.0\r\ncore-control-21  Microsoft Windows Server 2022 Standard\r\ndr-control-01    Microsoft Windows Server 2016 Standard\r\nraspberrypi      Raspbian 10\r\nsvcs-sql-01      Microsoft Windows Server 2016 Standard\r\nt147-ubuntu-01   Ubuntu 20.04\r\nt147-ubuntu-02   Ubuntu 20.04\r\nt147-ubuntu18-01 Ubuntu 18.04\r\nt147-win22-01    Microsoft Windows Server 2022 Standard<\/code><\/pre>\n\n\n\n<p>I decided to write a couple other wrapper functions for some other API methods that I thought I might end up using.  In the next few sections I&#8217;ll show how to find a specific job that was run, the activity around that job, and the specific results from the execution.  <\/p>\n\n\n\n<p>In Task 2 of the previous post (<a href=\"https:\/\/enterpriseadmins.org\/blog\/scripting\/getting-started-with-saltstack-config\">https:\/\/enterpriseadmins.org\/blog\/scripting\/getting-started-with-saltstack-config<\/a>), we created a job to push BgInfo to our test servers.  This function will return all jobs, but we&#8217;ll filter the output to just entries that contain bginfo.  The syntax will be <code>Get-SscJob | Where-Object {$_.name -match 'bginfo'}<\/code> and sample output would look like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>uuid     : b39de5cb-d01c-4cc7-a886-c746ae2b4150\nname     : EnterpriseAdmins BGInfo Test\ndesc     :\ncmd      : local\ntgt_uuid : e98739a9-a058-42a3-b3e4-73450de38ced\nfun      : state.apply\narg      : @{arg=System.Object&#91;]; kwarg=; hiddenArgsObj=}\nmasters  : {}\nmetadata : @{auth=}\ntgt_name : zCustomWinServerT147<\/code><\/pre>\n\n\n\n<p>When we ran that job, it generated some activity on our SSC appliance.  We&#8217;ll find that specific activity by looking for only the entries where the Job_UUID matches the output from the above command, and since we may have ran the task multiple times, we&#8217;ll also filter it for only instances started in the last couple of days.  The syntax will be <code>Get-SscActivity | Where-Object {$_.job_uuid -eq 'b39de5cb-d01c-4cc7-a886-c746ae2b4150' -AND $_.start_time -gt '2021-12-20'}<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>jid             : 20211222185741967000\nstate           : completed_all_successful\ncmd             : local\nuser            : bwuchner\nuser_uuid       : 6fe029b6-9e2e-4501-8c57-1776084bd3a8\njob_uuid        : b39de5cb-d01c-4cc7-a886-c746ae2b4150\njob_name        : EnterpriseAdmins BGInfo Test\njob_desc        :\ntgt_uuid        : e98739a9-a058-42a3-b3e4-73450de38ced\ntgt_name        : zCustomWinServerT147\ntgt_desc        :\ntgt_type        : compound\ntgt             : G@os:Windows and G@nodename:t147-win22-01\nsched_uuid      :\nsched_name      :                                                                                                       fun             : state.apply                                                                                           is_highstate    : False                                                                                                 job_source      : raas                                                                                                  expected        : 1\nreturned        : 1\nnot_returned    : 0\nreturned_good   : 1                                                                                                     returned_failed : 0                                                                                                     duration        :                                                                                                       masters_to      : {salt}                                                                                                masters_done    : {salt}\ncreate_time     : 2021-12-22T18:58:02.307191\norigination     : Ad-Hoc\nstart_time      : 2021-12-22T18:57:41.96700Z<\/code><\/pre>\n\n\n\n<p>And finally, we&#8217;ll want to find the status of all the data returned from that job.  We&#8217;ll get the JID value from above and include it in a filter to the last function we&#8217;ll be covering.  The final example syntax is: <code>(Get-SscReturn -jid 20211222185741967000).full_ret | Select-Object id, success<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>id                                     success\n--                                     -------\nt147-win22-01.lab.enterpriseadmins.org    True<\/code><\/pre>\n\n\n\n<p>These are just a few examples, but each function includes some help, so feel free to use PowerShell help to get any usage examples for the other functions.  For reference, here is a short list of the initial wrapper functions available:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nC:\\> Get-Command -Module SaltStackConfig\r\n\r\nCommandType     Name                                               Version    Source\r\n-----------     ----                                               -------    ------\r\nFunction        Connect-SscServer                                  0.0.5      SaltStackConfig\r\nFunction        Disconnect-SscServer                               0.0.5      SaltStackConfig\r\nFunction        Get-SscActivity                                    0.0.5      SaltStackConfig\r\nFunction        Get-SscData                                        0.0.5      SaltStackConfig\r\nFunction        Get-SscJob                                         0.0.5      SaltStackConfig\r\nFunction        Get-SscMaster                                      0.0.5      SaltStackConfig\r\nFunction        Get-SscMinionCache                                 0.0.5      SaltStackConfig\r\nFunction        Get-SscReturn                                      0.0.5      SaltStackConfig\r\nFunction        Get-SscSchedule                                    0.0.5      SaltStackConfig<\/code><\/pre>\n\n\n\n<p>If you run into any issues, or think of another function that would be helpful to have, please feel free to submit an issue on the Github repo at  <a href=\"https:\/\/github.com\/vmware\/PowerCLI-Example-Scripts\">https:\/\/github.com\/vmware\/PowerCLI-Example-Scripts<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous post (here), we looked into Getting Started with SaltStack Config. We created and kicked off a few tasks from the web interface. Occasionally we&#8217;ll need to report on some data as well. The web interface offers the &hellip; <a href=\"https:\/\/enterpriseadmins.org\/blog\/scripting\/getting-started-with-saltstackconfig-powershell-module\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":6,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[9,3],"tags":[],"class_list":["post-1612","post","type-post","status-publish","format-standard","hentry","category-lab-infrastructure","category-scripting"],"_links":{"self":[{"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/posts\/1612","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/comments?post=1612"}],"version-history":[{"count":6,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/posts\/1612\/revisions"}],"predecessor-version":[{"id":1618,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/posts\/1612\/revisions\/1618"}],"wp:attachment":[{"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/media?parent=1612"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/categories?post=1612"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/tags?post=1612"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}