<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://powershellyoungteam.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://powershellyoungteam.github.io/" rel="alternate" type="text/html" /><updated>2026-02-16T21:19:18+00:00</updated><id>https://powershellyoungteam.github.io/feed.xml</id><title type="html">PowerShell Young Team</title><subtitle>You can take the sysadmin out of the scheme, but you can&apos;t take the scheme out the sysadmin... A blog on my adventures with PowerShell (plus other tech!) as I attempt to automate myself a quiet life!</subtitle><author><name>Steven Wight</name><email>PoShYoungTeam@Hotmail.com</email></author><entry><title type="html">Loops as a machine gun</title><link href="https://powershellyoungteam.github.io/2025/03/20/Loops-as-a-machine-gun.html" rel="alternate" type="text/html" title="Loops as a machine gun" /><published>2025-03-20T00:00:00+00:00</published><updated>2025-03-20T00:00:00+00:00</updated><id>https://powershellyoungteam.github.io/2025/03/20/Loops-as-a-machine-gun</id><content type="html" xml:base="https://powershellyoungteam.github.io/2025/03/20/Loops-as-a-machine-gun.html"><![CDATA[<p>COMMING SOON!</p>]]></content><author><name>Steven Wight</name><email>PoShYoungTeam@Hotmail.com</email></author><category term="Other" /><summary type="html"><![CDATA[COMMING SOON!]]></summary></entry><entry><title type="html">Processes Built in Blood</title><link href="https://powershellyoungteam.github.io/2025/03/15/Processes-Built-in-blood.html" rel="alternate" type="text/html" title="Processes Built in Blood" /><published>2025-03-15T00:00:00+00:00</published><updated>2025-03-15T00:00:00+00:00</updated><id>https://powershellyoungteam.github.io/2025/03/15/Processes-Built-in-blood</id><content type="html" xml:base="https://powershellyoungteam.github.io/2025/03/15/Processes-Built-in-blood.html"><![CDATA[<p>COMMING SOON!</p>]]></content><author><name>Steven Wight</name><email>PoShYoungTeam@Hotmail.com</email></author><category term="Other" /><summary type="html"><![CDATA[COMMING SOON!]]></summary></entry><entry><title type="html">Using Psbluesky And Fun With_facets</title><link href="https://powershellyoungteam.github.io/2025/03/14/Using-PSBlueSky-and-Fun-With_Facets.html" rel="alternate" type="text/html" title="Using Psbluesky And Fun With_facets" /><published>2025-03-14T00:00:00+00:00</published><updated>2025-03-14T00:00:00+00:00</updated><id>https://powershellyoungteam.github.io/2025/03/14/Using-PSBlueSky-and-Fun-With_Facets</id><content type="html" xml:base="https://powershellyoungteam.github.io/2025/03/14/Using-PSBlueSky-and-Fun-With_Facets.html"><![CDATA[<p><img src="/assets/images/Hill_Night.png" alt="Screenshot" /></p>

<h1 id="using-psbluesky-and-fun-with-facets">Using PSBlueSky and Fun with Facets</h1>

<p>COMMING SOON!</p>]]></content><author><name>Steven Wight</name><email>PoShYoungTeam@Hotmail.com</email></author><category term="Other" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Powershell Profiles Keepass And Psbluesky</title><link href="https://powershellyoungteam.github.io/2024/11/22/PowerShell-Profiles-KeePass-and-PSBlueSky.html" rel="alternate" type="text/html" title="Powershell Profiles Keepass And Psbluesky" /><published>2024-11-22T00:00:00+00:00</published><updated>2024-11-22T00:00:00+00:00</updated><id>https://powershellyoungteam.github.io/2024/11/22/PowerShell-Profiles-KeePass-and-PSBlueSky</id><content type="html" xml:base="https://powershellyoungteam.github.io/2024/11/22/PowerShell-Profiles-KeePass-and-PSBlueSky.html"><![CDATA[<p><img src="/assets/images/flats2.png" alt="Screenshot" /></p>

<h1 id="powershell-profiles-keepass-and-psbluesky">PowerShell Profiles, KeePass and PSBlueSky</h1>

<p>Was listening to the PowerShell Podcast and heard about a few peps had moved over to BlueSky, also about Jeff Hick’s module to interact with it.</p>

<p>Had a wee recce, in the github repo’s README, it is suggested:</p>

<blockquote>
  <p>For automation purposes, you can use the Secrets management module to store your credential. Write your own code to retrieve the credential and pass it to the module commands.</p>
</blockquote>

<p>hmm… my wee bit in my profile for getting my OpenAI key should work for this!</p>

<p>what we need:</p>

<blockquote>
  <ul>
    <li>
      <p>Jeff Hick’s <strong>PSBlueSky</strong> - <a href="https://github.com/jdhitsolutions/PSBluesky">https://github.com/jdhitsolutions/PSBluesky</a></p>
    </li>
    <li>
      <p>Justin Grote’s <strong>SecretManagement.Keepass</strong> - <a href="https://github.com/JustinGrote/SecretManagement.KeePass">https://github.com/JustinGrote/SecretManagement.KeePass</a></p>
    </li>
  </ul>
</blockquote>

<h2 id="secretmanagementkeepass">SecretManagement.Keepass</h2>

<p>So I already had KeePass, if you don’t then Grab and install KeePass from here <a href="https://keepass.info">https://keepass.info</a> (It’s open source so it’s buckshee !!)</p>

<p>Install KeePass and create a Vault with master password or Keyfile (or both)</p>

<p>You will also create a BlueSky account from <a href="https://bsky.app/">https://bsky.app/</a> and store the username and password in the vault</p>

<p><strong>NOTE:</strong> Username is case sensitive too!, also don’t be like me and put the @ sign before the username, so like <strong>PoshYoungTeam.bsky.social</strong>, NOT <strong>@PoshYoungTeam.bsky.social</strong></p>

<p><strong>ALSO:</strong> I found it best just to put your secrets that you want to retrieve via PowerShell in the root of the Vault, hit problems with I put them in a sub group, so best as per below screenshot.</p>

<p><img src="/assets/images/VaultPicRoot.jpg" alt="VaultPicRoot" /></p>

<p>To install the SecretManagement.Keepass module just download from the PowerShell gallery.</p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">Install-Module</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="nx">SecretManagement.KeePass</span><span class="w">
</span></code></pre></div></div>

<p>Import the module (Import-module SecretManagement.KeePass) and then you need to register the vault so the module knows where and how to access it (below is for a master password only vault, there is a -keyfile argument you can use for keyfiles)</p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">Register-KeepassSecretVault</span><span class="w"> </span><span class="nt">-Path</span><span class="w"> </span><span class="err">&lt;</span><span class="nx">Path</span><span class="w"> </span><span class="nx">to</span><span class="w"> </span><span class="nx">Keepass</span><span class="w"> </span><span class="nx">Vault</span><span class="err">&gt;</span><span class="w"> </span><span class="nt">-UseMasterPassword</span><span class="w">
</span></code></pre></div></div>

<p><img src="/assets/images/registervault.jpg" alt="registerVault" /></p>

<p>You can use Test-SecretVault to check if it worked (will return Boolean) like below</p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">Test-SecretVault</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="err">&lt;</span><span class="nx">Name</span><span class="w"> </span><span class="nx">of</span><span class="w"> </span><span class="nx">vault</span><span class="err">&gt;</span><span class="w">
</span></code></pre></div></div>

<p><img src="/assets/images/Testsecvault.jpg" alt="TestSecVault" /></p>

<h2 id="psbluesky">PSBlueSky</h2>

<p>Now we need to install and import PSBlueSky module</p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">Install-Module</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="nx">PSBlueSky</span><span class="w"> 
</span><span class="n">Import-Module</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="nx">PSBlueSky</span><span class="w">
</span></code></pre></div></div>

<p>So now we need to get the BlueSky Credentials from the vault and use it for PSBlueSky’s <strong>Start-BSkySession</strong> cmdlet, after that you (Hopefully) should be skeeting in no time!!</p>

<p>So let’s grab the cred’s and start a session</p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$BskyCreds</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Get-Secret</span><span class="w"> </span><span class="nt">-Vault</span><span class="w"> </span><span class="nx">PowerShell</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="nx">BlueSky</span><span class="w">
</span><span class="n">Start-BSkySession</span><span class="w"> </span><span class="nt">-Credential</span><span class="w"> </span><span class="nv">$BskyCreds</span><span class="w">
</span></code></pre></div></div>

<p><img src="/assets/images/BskySession.jpg" alt="BskySession" /></p>

<p>and use <strong>New-BskyPost</strong> to send a Skeet from the CLI…</p>

<p><img src="/assets/images/Skeet.JPG" alt="Skeet" /></p>

<p>Bar the usual get-help and readme on the GitHub repo, also has this more informative version of get-command -module PSblueSky: <strong>Get-BskyModuleInfo</strong>, which I think is pure dead brilliant!</p>

<p><img src="/assets/images/Bskymoduleinfo.jpg" alt="Bskymoduleinfo" /></p>

<p>So for me, I just add this into my profile and when I start a session, I just enter my KeePass Vault password and I am ready to rock and roll!</p>

<p>I have set it up so it also display’s my Skeets from my feed so I can see how they are doing!</p>

<p>(don’t need the test-SecretVault, I have left it in there tho..)</p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">import-module</span><span class="w"> </span><span class="nx">PSBlueSky</span><span class="w"> 
</span><span class="n">Import-Module</span><span class="w"> </span><span class="nx">SecretManagement.KeePass</span><span class="w">

</span><span class="n">test-SecretVault</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="nx">PowerShell</span><span class="w">
</span><span class="nv">$BskyCreds</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Get-Secret</span><span class="w"> </span><span class="nt">-Vault</span><span class="w"> </span><span class="nx">PowerShell</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="nx">BlueSky</span><span class="w">
</span><span class="n">Start-BSkySession</span><span class="w"> </span><span class="nt">-Credential</span><span class="w"> </span><span class="nv">$BskyCreds</span><span class="w">
</span><span class="nv">$BskyFeeds</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Get-BskyFeed</span><span class="w"> 
</span><span class="nv">$BskyFeeds</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">Where-Object</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="bp">$_</span><span class="o">.</span><span class="nf">Author</span><span class="w"> </span><span class="o">-eq</span><span class="w"> </span><span class="nv">$BskyCreds</span><span class="o">.</span><span class="nf">username</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p><img src="/assets/images/ProfileBskyFeed.jpg" alt="ProfileWorking" /></p>

<p>Hope this helps :)</p>]]></content><author><name>Steven Wight</name><email>PoShYoungTeam@Hotmail.com</email></author><category term="Other" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Ad Reports With Gui Controller</title><link href="https://powershellyoungteam.github.io/2023/09/01/AD-Reports-with-GUI-Controller.html" rel="alternate" type="text/html" title="Ad Reports With Gui Controller" /><published>2023-09-01T00:00:00+00:00</published><updated>2023-09-01T00:00:00+00:00</updated><id>https://powershellyoungteam.github.io/2023/09/01/AD-Reports-with-GUI-Controller</id><content type="html" xml:base="https://powershellyoungteam.github.io/2023/09/01/AD-Reports-with-GUI-Controller.html"><![CDATA[<p><img src="/assets/images/port_louis.png" alt="Screenshot" /></p>

<h1 id="gui-controller-to-run-ad-report-tools">GUI Controller to run AD Report Tools</h1>

<p>So a few weeks back my boss went on holiday, and he asked me to run some AD reports for him when he was off.</p>

<p>I actually made the “Scripts” that pulled these reports many moons ago.</p>

<p>When I looked at them and how they were all in different locations, outputting CSVs to different folders, I thought I can make this so much better (and get brownie points!)</p>

<p>I have been using the great resource <strong>PoshCode/PowerShellPracticeAndStyle: The Unofficial PowerShell Best Practices and Style Guide</strong> <a href="https://github.com/PoshCode/PowerShellPracticeAndStyle">https://github.com/PoshCode/PowerShellPracticeAndStyle</a> to try and improve my scripts and (try) to produce clean code.</p>

<p>One thing I really liked (and I was falling down badly with) was the idea of tools and controllers. So with this in mind, I created some functions that used Cmdlets from the <strong>Active Directory module</strong> <a href="https://learn.microsoft.com/en-us/powershell/module/activedirectory/?view=windowsserver2022-ps">https://learn.microsoft.com/en-us/powershell/module/activedirectory/?view=windowsserver2022-ps</a> and also Doug Finke’s amazeballs <strong>ImportExcel module</strong> <a href="https://github.com/dfinke/ImportExcel">https://github.com/dfinke/ImportExcel</a>.</p>

<p>These were:</p>

<ul>
  <li><strong>Get-PYTALLADComputers</strong> - Function to extract all AD Computer objects for a domain into a CSV &amp; spreadsheet</li>
  <li><strong>Get-PYTALLADusers</strong> - Function to extract all AD User objects for a domain into a CSV &amp; spreadsheet</li>
  <li><strong>Get-PYTUserGroupMembership</strong> - Function to extract all members of AD groups populated with user AD objects with a certain string in the names details into a CSV &amp; spreadsheet</li>
  <li><strong>Get-PYTAdminGroups</strong> - Function to extract all Admin Groups &amp; memberships details from multiple Domains into a CSV &amp; spreadsheet, made specifically for admin groups (can be used for others)</li>
</ul>

<p>These functions are nothing special, ALL AD Computers and Users would pull out all those objects from AD into an array, then loop through that array, putting info into a PS custom object (we have some custom properties for those objects in our AD that come out as non-string objects, so I used to PS Custom object to turn them into strings for export to CSV) once the CSV has been finished (handy for other scripts to read, as not got my head fully around ImportExcel yet) we basically create a .Xlsx from it and output to our chosen folder (this case C:\temp, but easy to change as it’s a parameter that can be passed to the function.</p>

<p>Get-PYTUserGroupMembership literally pulls out the members of AD groups that have been populated with only User AD objects (we control access to VDI pools and certain Group Policies via these, so its handy), it extracts all the AD groups that match the search string we use to identify our Pool VDI AD groups (but aren’t prefix’d with zz as that is how we mark AD groups that are to be decom’d), then loops through the groups, each group it extracts the membership, looping through the membership doing a lookup to get more information on the member and pumping into a CSV file (which you guessed it, will be made into a .Xlsx!)</p>

<p>Get-PYTAdminGroups is basically Get-PYTUserGroupMembership but it will also search through multiple domains! (Like our Pool VDI AD Groups, we use a naming convention for all our Admin groups)</p>

<p><strong>Parameters - PowerShell Universal</strong> <a href="https://docs.powershelluniversal.com/automation/scripts/parameters">https://docs.powershelluniversal.com/automation/scripts/parameters</a> - This blog helped with me passing multiple domains as a parameter as wasn’t something I had done before. hopefully this code snippet explains better than me..</p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w"> </span><span class="n">HelpMessage</span><span class="o">=</span><span class="s2">"Enter in a Domains to extact AD groups members from, accepted values (multiple): PYT, PYTUAT, PYTDEV"</span><span class="p">)</span><span class="err">]</span><span class="w">
</span><span class="p">[</span><span class="n">ValidateSet</span><span class="p">(</span><span class="s1">'PYT'</span><span class="p">,</span><span class="s1">'PYTUAT'</span><span class="p">,</span><span class="s1">'PYTDEV'</span><span class="p">)]</span><span class="w"> </span><span class="p">[</span><span class="n">String</span><span class="p">]</span><span class="w"> </span><span class="nv">$Domain</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="s1">'PYT'</span><span class="p">,</span><span class="s1">'PYTUAT'</span><span class="p">,</span><span class="s1">'PYTDEV'</span><span class="p">),</span><span class="w">
</span></code></pre></div></div>

<p>I stuck them in a module which my controller script can call!</p>

<p>Now I have made scripts, modules etc… before and shared them with colleagues, but not everyone loves CLI like I do, and basically a lot of people don’t use them.</p>

<p>So I figured it was time to make the controller scripts fire up a GUI and see if that would get my colleagues to use it more.</p>

<p>I did some research and found these which helped massively!</p>

<p><strong>Creating a custom input box - PowerShell - Microsoft Learn</strong> <a href="https://learn.microsoft.com/en-us/powershell/scripting/samples/creating-a-custom-input-box?view=powershell-7.3">https://learn.microsoft.com/en-us/powershell/scripting/samples/creating-a-custom-input-box?view=powershell-7.3</a> - This was my first stop, helped me pull in the .NET framework form-building features, build the form and labels add OK/ cancel buttons!</p>

<p><strong>Powershell and Forms (part 3) – Checkboxes - ServerFixes</strong> <a href="https://serverfixes.com/powershell-checkboxes">https://serverfixes.com/powershell-checkboxes</a> - this helped me add the checkboxes for what scripts you want to run.</p>

<p>Also I found that ChatGPT was decent at building the barebones of a GUI too! If you explain what you want (form x size, with a label that says this, dropdown etc…) defo worth a play with as I found it can be quite a time saver, unless you are like me and won’t stop tinkering with size and postion of things so you spend loads of time on it anyway!</p>

<p>So here is the GUI!</p>

<p><img src="/assets/images/ADReportsGUI.png" alt="GUI" /></p>

<p>I have also built a much more complicated GUI controller for a Nutanix module I am making, but it’s still in progress!</p>

<p>Right so here is how the GUI was made!</p>

<p>first you need to make sure you load up the .NET framework form building features, dead simple!</p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">Add-Type</span><span class="w"> </span><span class="nt">-AssemblyName</span><span class="w"> </span><span class="nx">System.Windows.Forms</span><span class="w">
</span><span class="n">Add-Type</span><span class="w"> </span><span class="nt">-AssemblyName</span><span class="w"> </span><span class="nx">System.Drawing</span><span class="w">
</span></code></pre></div></div>

<p>Then create the form and set Title, Size, screen position and Font..</p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ADReportControllerForm</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">New-Object</span><span class="w"> </span><span class="nx">System.Windows.Forms.Form</span><span class="w">
</span><span class="nv">$ADReportControllerForm</span><span class="o">.</span><span class="nf">Text</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'PYT AD Reports'</span><span class="w">
</span><span class="nv">$ADReportControllerForm</span><span class="o">.</span><span class="nf">Size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">New-Object</span><span class="w"> </span><span class="nx">System.Drawing.Size</span><span class="p">(</span><span class="mi">400</span><span class="p">,</span><span class="mi">270</span><span class="p">)</span><span class="w">
</span><span class="nv">$ADReportControllerForm</span><span class="o">.</span><span class="nf">StartPosition</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'CenterScreen'</span><span class="w">
</span><span class="nv">$ADReportControllerForm</span><span class="o">.</span><span class="nf">Font</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="err">‘</span><span class="n">Microsoft</span><span class="w"> </span><span class="nx">Sans</span><span class="w"> </span><span class="nx">Serif</span><span class="p">,</span><span class="nx">10</span><span class="err">’</span><span class="w">
</span></code></pre></div></div>

<p>Create the label/Text</p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$TextHelp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">New-Object</span><span class="w"> </span><span class="nx">System.Windows.Forms.Label</span><span class="w">
</span><span class="nv">$TextHelp</span><span class="o">.</span><span class="nf">Location</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">New-Object</span><span class="w"> </span><span class="nx">System.Drawing.Point</span><span class="p">(</span><span class="mi">50</span><span class="p">,</span><span class="mi">20</span><span class="p">)</span><span class="w">
</span><span class="nv">$TextHelp</span><span class="o">.</span><span class="nf">Size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">New-Object</span><span class="w"> </span><span class="nx">System.Drawing.Size</span><span class="p">(</span><span class="mi">350</span><span class="p">,</span><span class="mi">20</span><span class="p">)</span><span class="w">
</span><span class="nv">$TextHelp</span><span class="o">.</span><span class="nf">Text</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'Select the reports you want to run, then click RUN'</span><span class="w">
</span><span class="nv">$ADReportControllerForm</span><span class="o">.</span><span class="nf">Controls</span><span class="o">.</span><span class="nf">Add</span><span class="p">(</span><span class="nv">$TextHelp</span><span class="p">)</span><span class="w">
</span></code></pre></div></div>

<p>You create the checkbox like below, setting them as pre checked, and giving them a text label</p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$AllADCompCheckbox</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">New-Object</span><span class="w"> </span><span class="nx">System.Windows.Forms.Checkbox</span><span class="w"> 
</span><span class="nv">$AllADCompCheckbox</span><span class="o">.</span><span class="nf">Location</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">New-Object</span><span class="w"> </span><span class="nx">System.Drawing.Size</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">50</span><span class="p">)</span><span class="w"> 
</span><span class="nv">$AllADCompCheckbox</span><span class="o">.</span><span class="nf">Size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">New-Object</span><span class="w"> </span><span class="nx">System.Drawing.Size</span><span class="p">(</span><span class="mi">500</span><span class="p">,</span><span class="mi">20</span><span class="p">)</span><span class="w">
</span><span class="nv">$AllADCompCheckbox</span><span class="o">.</span><span class="nf">Text</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Run All PYT AD Computers Report"</span><span class="w">
</span><span class="nv">$AllADCompCheckbox</span><span class="o">.</span><span class="nf">TabIndex</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="w">
</span><span class="nv">$AllADCompCheckbox</span><span class="o">.</span><span class="nf">Checked</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">$true</span><span class="w">
</span><span class="nv">$ADReportControllerForm</span><span class="o">.</span><span class="nf">Controls</span><span class="o">.</span><span class="nf">Add</span><span class="p">(</span><span class="nv">$AllADCompCheckbox</span><span class="p">)</span><span class="w">
</span></code></pre></div></div>

<p>Then the Run (OK) and Cancel buttons (see Dialogue result)</p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$okButton</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">New-Object</span><span class="w"> </span><span class="nx">System.Windows.Forms.Button</span><span class="w">
</span><span class="nv">$okButton</span><span class="o">.</span><span class="nf">Location</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">New-Object</span><span class="w"> </span><span class="nx">System.Drawing.Point</span><span class="p">(</span><span class="mi">75</span><span class="p">,</span><span class="mi">180</span><span class="p">)</span><span class="w">
</span><span class="nv">$okButton</span><span class="o">.</span><span class="nf">Size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">New-Object</span><span class="w"> </span><span class="nx">System.Drawing.Size</span><span class="p">(</span><span class="mi">75</span><span class="p">,</span><span class="mi">23</span><span class="p">)</span><span class="w">
</span><span class="nv">$okButton</span><span class="o">.</span><span class="nf">Text</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'RUN'</span><span class="w">
</span><span class="nv">$okButton</span><span class="o">.</span><span class="nf">DialogResult</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="n">System.Windows.Forms.DialogResult</span><span class="p">]::</span><span class="n">OK</span><span class="w">
</span><span class="nv">$okButton</span><span class="o">.</span><span class="nf">TabIndex</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">4</span><span class="w">
</span><span class="nv">$ADReportControllerForm</span><span class="o">.</span><span class="nf">AcceptButton</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nv">$okButton</span><span class="w">
</span><span class="nv">$ADReportControllerForm</span><span class="o">.</span><span class="nf">Controls</span><span class="o">.</span><span class="nf">Add</span><span class="p">(</span><span class="nv">$okButton</span><span class="p">)</span><span class="w">
</span><span class="nv">$cancelButton</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">New-Object</span><span class="w"> </span><span class="nx">System.Windows.Forms.Button</span><span class="w">
</span><span class="nv">$cancelButton</span><span class="o">.</span><span class="nf">Location</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">New-Object</span><span class="w"> </span><span class="nx">System.Drawing.Point</span><span class="p">(</span><span class="mi">200</span><span class="p">,</span><span class="mi">180</span><span class="p">)</span><span class="w">
</span><span class="nv">$cancelButton</span><span class="o">.</span><span class="nf">Size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">New-Object</span><span class="w"> </span><span class="nx">System.Drawing.Size</span><span class="p">(</span><span class="mi">75</span><span class="p">,</span><span class="mi">23</span><span class="p">)</span><span class="w">
</span><span class="nv">$cancelButton</span><span class="o">.</span><span class="nf">Text</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'Cancel'</span><span class="w">
</span><span class="nv">$cancelButton</span><span class="o">.</span><span class="nf">DialogResult</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="n">System.Windows.Forms.DialogResult</span><span class="p">]::</span><span class="n">Cancel</span><span class="w">
</span><span class="nv">$cancelButton</span><span class="o">.</span><span class="nf">TabIndex</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">5</span><span class="w">
</span><span class="nv">$ADReportControllerForm</span><span class="o">.</span><span class="nf">CancelButton</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nv">$cancelButton</span><span class="w">
</span><span class="nv">$ADReportControllerForm</span><span class="o">.</span><span class="nf">Controls</span><span class="o">.</span><span class="nf">Add</span><span class="p">(</span><span class="nv">$cancelButton</span><span class="p">)</span><span class="w">
</span></code></pre></div></div>

<p>This will make sure the GUI doesn’t get hidden under your many open windows (if like me !)</p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ADReportControllerForm</span><span class="o">.</span><span class="nf">Topmost</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">$true</span><span class="w">
</span></code></pre></div></div>

<p>If the OK/Run button is pressed, then we check if the checkboxes are set to true/Checked and fire the function to create that report!</p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">if</span><span class="w"> </span><span class="p">(</span><span class="nv">$result</span><span class="w"> </span><span class="o">-eq</span><span class="w"> </span><span class="p">[</span><span class="n">System.Windows.Forms.DialogResult</span><span class="p">]::</span><span class="n">OK</span><span class="p">)</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="err"> </span><span class="w"> </span><span class="err"> </span><span class="w"> </span><span class="kr">if</span><span class="p">(</span><span class="bp">$true</span><span class="w"> </span><span class="o">-eq</span><span class="w"> </span><span class="nv">$AllADCompCheckbox</span><span class="o">.</span><span class="nf">Checked</span><span class="p">){</span><span class="w">
</span><span class="err"> </span><span class="w"> </span><span class="err"> </span><span class="w"> </span><span class="err"> </span><span class="w"> </span><span class="err"> </span><span class="w"> </span><span class="n">Get-PYTALLADComputers</span><span class="w"> </span><span class="nt">-Verbose</span><span class="w">
</span><span class="err"> </span><span class="w"> </span><span class="err"> </span><span class="w"> </span><span class="p">}</span><span class="w">
</span><span class="err"> </span><span class="w"> </span><span class="err"> </span><span class="w"> </span><span class="kr">if</span><span class="p">(</span><span class="bp">$true</span><span class="w"> </span><span class="o">-eq</span><span class="w"> </span><span class="nv">$AllADUserCheckbox</span><span class="o">.</span><span class="nf">Checked</span><span class="p">){</span><span class="w">
</span><span class="err"> </span><span class="w"> </span><span class="err"> </span><span class="w"> </span><span class="err"> </span><span class="w"> </span><span class="err"> </span><span class="w"> </span><span class="n">Get-PYTALLADusers</span><span class="w"> </span><span class="nt">-Verbose</span><span class="w">
</span><span class="err"> </span><span class="w"> </span><span class="err"> </span><span class="w"> </span><span class="p">}</span><span class="w">
</span><span class="err"> </span><span class="w"> </span><span class="err"> </span><span class="w"> </span><span class="kr">if</span><span class="p">(</span><span class="bp">$true</span><span class="w"> </span><span class="o">-eq</span><span class="w"> </span><span class="nv">$PoolVDICheckbox</span><span class="o">.</span><span class="nf">Checked</span><span class="p">){</span><span class="w">
</span><span class="err"> </span><span class="w"> </span><span class="err"> </span><span class="w"> </span><span class="err"> </span><span class="w"> </span><span class="err"> </span><span class="w"> </span><span class="n">Get-PYTUserGroupMembership</span><span class="w"> </span><span class="nx">VDI_POOL</span><span class="w"> </span><span class="nt">-Verbose</span><span class="w">
</span><span class="err"> </span><span class="w"> </span><span class="err"> </span><span class="w"> </span><span class="p">}</span><span class="w">
</span><span class="err"> </span><span class="w"> </span><span class="err"> </span><span class="w"> </span><span class="kr">if</span><span class="p">(</span><span class="bp">$true</span><span class="w"> </span><span class="o">-eq</span><span class="w"> </span><span class="nv">$SecurityGroupCheckbox</span><span class="o">.</span><span class="nf">Checked</span><span class="p">){</span><span class="w">
</span><span class="err"> </span><span class="w"> </span><span class="err"> </span><span class="w"> </span><span class="err"> </span><span class="w"> </span><span class="err"> </span><span class="w"> </span><span class="n">Get-PYTAdminGroups</span><span class="w"> </span><span class="nt">-Verbose</span><span class="w">
</span><span class="err"> </span><span class="w"> </span><span class="err"> </span><span class="w"> </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="kr">else</span><span class="p">{</span><span class="w">
</span><span class="err"> </span><span class="w"> </span><span class="err"> </span><span class="w"> </span><span class="n">Write-Warning</span><span class="w"> </span><span class="s2">"Exiting Script"</span><span class="w">
</span><span class="err"> </span><span class="w"> </span><span class="err"> </span><span class="w"> </span><span class="kr">break</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>Viola ! My manager can run all his AD reports at the click of a button!!</p>

<p>You can find the files here, and any questions, Just shout :)</p>

<p><a href="https://github.com/PowerShellYoungTeam/Active-Directory">https://github.com/PowerShellYoungTeam/Active-Directory</a></p>]]></content><author><name>Steven Wight</name><email>PoShYoungTeam@Hotmail.com</email></author><category term="Other" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Bloomberg Terminal Download Page</title><link href="https://powershellyoungteam.github.io/2023/06/06/Bloomberg-Terminal-Download-Page.html" rel="alternate" type="text/html" title="Bloomberg Terminal Download Page" /><published>2023-06-06T00:00:00+00:00</published><updated>2023-06-06T00:00:00+00:00</updated><id>https://powershellyoungteam.github.io/2023/06/06/Bloomberg-Terminal-Download-Page</id><content type="html" xml:base="https://powershellyoungteam.github.io/2023/06/06/Bloomberg-Terminal-Download-Page.html"><![CDATA[<p><img src="/assets/images/redroad2.jpg" alt="Screenshot" /></p>

<h1 id="webscraping-bloomberg-terminal-download-page-for-new-releases">Webscraping Bloomberg Terminal Download Page for New Releases</h1>

<blockquote>
  <p>NB - this only works in Windows Powershell at the moment, in Core it throws the below error with the .ParsedHtml.getElementsByTagName and still to get to the bottom of that!</p>
</blockquote>

<p><img src="/assets/images/BloomyCorePoshFail.jpg" alt="pwsh7error" /></p>

<p>Working for an Investment Bank, one of my jobs is updating the version of Bloomberg Terminal in Config Manager and making sure our DR machines that have it update (normally they auto-update but it requires a login which I am not doing each month on most of the DR estate)</p>

<p>I used to check the Bloomberg download page each day of the month until the new update came out, but after the one man module making machine Adam Bacon (psDevUK) - <a href="https://github.com/psDevUK">https://github.com/psDevUK</a> kindly wrote me a script that would scrape data off a webpage for another thing I asked about, I had an idea.</p>

<p>So using his code and a lot of playing about with regex to pull out the Month of the release from the bloomberg software update download page <a href="https://www.bloomberg.com/professional/support/software-updates/">https://www.bloomberg.com/professional/support/software-updates/</a> (I wish I did this write up sooner so I could better explain the regex bit, but it basically looks for the table row with Bloomberg Terminal - New/Upgrade Installation and then pulls out the Month text )</p>

<p><img src="/assets/images/BloombergUpdatepage.jpg" alt="BloomyDownload" /></p>

<p>Here is the function below, you can also grab it from <a href="https://github.com/PowerShellYoungTeam/Trading-Apps">https://github.com/PowerShellYoungTeam/Trading-Apps</a></p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">function</span><span class="w"> </span><span class="nf">Get-BloombergRelease</span><span class="p">{</span><span class="w">
	</span><span class="cm">&lt;#
	</span><span class="cs">.SYNOPSIS</span><span class="cm">
	Function to check for new releases of Bloomberg Terminal
	by Steven Wight
	</span><span class="cs">.DESCRIPTION</span><span class="cm">
	Get-BloombergRelease &lt;URL&gt; (default https://www.bloomberg.com/professional/support/software-updates/)
	</span><span class="cs">.EXAMPLE</span><span class="cm">
	Get-BloombergRelease
	</span><span class="cs">.Notes</span><span class="cm">
	You can change and even pipe the URL, but unless Bloomberg change the URL, it's pretty pointless to be fair, more of a personal exercise me doing it. NB currently only works with Windows PowerShell
	#&gt;</span><span class="w">

	</span><span class="p">[</span><span class="n">CmdletBinding</span><span class="p">()]</span><span class="w">
	</span><span class="kr">Param</span><span class="w">
	</span><span class="p">(</span><span class="w">
		</span><span class="p">[</span><span class="n">Parameter</span><span class="p">(</span><span class="n">ValueFromPipeline</span><span class="o">=</span><span class="bp">$true</span><span class="p">,</span><span class="n">Position</span><span class="o">=</span><span class="mi">0</span><span class="p">)]</span><span class="w">
		</span><span class="nv">$URL</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'https://www.bloomberg.com/professional/support/software-updates/'</span><span class="w">	
	</span><span class="p">)</span><span class="w">

	</span><span class="kr">Begin</span><span class="w"> </span><span class="p">{</span><span class="w">

		</span><span class="nv">$Start</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Get-Date</span><span class="w">
		</span><span class="nx">Write-Verbose</span><span class="w"> </span><span class="s2">"Scraping </span><span class="si">$(</span><span class="nv">$URL</span><span class="si">)</span><span class="s2"> for data at </span><span class="si">$(</span><span class="p">(</span><span class="n">Get-Date</span><span class="p">)</span><span class="o">.</span><span class="nf">ToString</span><span class="p">(</span><span class="s1">'yyyy-MM-dd HH:MM:ss'</span><span class="p">)</span><span class="si">)</span><span class="s2">"</span><span class="w">

	</span><span class="p">}</span><span class="w">

	</span><span class="kr">Process</span><span class="w"> </span><span class="p">{</span><span class="w">

		</span><span class="n">Write-Verbose</span><span class="w"> </span><span class="s2">"Extracting Data from </span><span class="si">$(</span><span class="nv">$URL</span><span class="si">)</span><span class="s2">"</span><span class="w">
		</span><span class="nv">$page</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Invoke-WebRequest</span><span class="w"> </span><span class="nt">-Uri</span><span class="w"> </span><span class="nv">$URL</span><span class="w">

		</span><span class="c">#got through the page data and find the Table Row with the text we are looking for</span><span class="w">
		</span><span class="nv">$TRwithData</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nv">$page</span><span class="o">.</span><span class="nf">ParsedHtml</span><span class="o">.</span><span class="nf">getElementsByTagName</span><span class="p">(</span><span class="s1">'tr'</span><span class="p">)</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">Where-Object</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="bp">$_</span><span class="o">.</span><span class="nf">innerText</span><span class="w"> </span><span class="o">-like</span><span class="w"> </span><span class="s2">"Bloomberg Terminal - New/Upgrade Installation*"</span><span class="p">}</span><span class="w">
		</span><span class="nv">$HTMLwithData</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nv">$TRwithData</span><span class="o">.</span><span class="nf">outerHTML</span><span class="w">

		</span><span class="c">#use regex to grab the month text, lets set the strings we need</span><span class="w">
		</span><span class="nv">$firstString</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'&lt;td class="date"&gt;'</span><span class="w">
		</span><span class="nv">$secondString</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'&lt;/td&gt;'</span><span class="w">

		</span><span class="c">#Regex pattern to compare two strings</span><span class="w">
		</span><span class="nv">$pattern</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"</span><span class="nv">$firstString</span><span class="s2">(.*?)</span><span class="nv">$secondString</span><span class="s2">"</span><span class="w">

		</span><span class="c">#Perform the match operation to grab the month string</span><span class="w">
		</span><span class="nv">$ReleaseMonth</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="n">regex</span><span class="p">]::</span><span class="n">Match</span><span class="p">(</span><span class="nv">$HTMLwithData</span><span class="p">,</span><span class="nv">$pattern</span><span class="p">)</span><span class="o">.</span><span class="n">Groups</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="nf">Value</span><span class="w">

		</span><span class="kr">if</span><span class="w"> </span><span class="p">(</span><span class="bp">$null</span><span class="w"> </span><span class="o">-eq</span><span class="w"> </span><span class="nv">$ReleaseMonth</span><span class="p">){</span><span class="w">

			</span><span class="n">Write-Verbose</span><span class="w"> </span><span class="s2">"Can't find the Download in </span><span class="si">$(</span><span class="nv">$URL</span><span class="si">)</span><span class="s2">"</span><span class="w">
			</span><span class="kr">break</span><span class="w">

		</span><span class="p">}</span><span class="kr">else</span><span class="p">{</span><span class="w">

			</span><span class="n">Write-Verbose</span><span class="w"> </span><span class="s2">"Found </span><span class="si">$(</span><span class="nv">$ReleaseMonth</span><span class="si">)</span><span class="s2"> Month in </span><span class="si">$(</span><span class="nv">$URL</span><span class="si">)</span><span class="s2">"</span><span class="w">

		</span><span class="p">}</span><span class="w">
	</span><span class="p">}</span><span class="w">

</span><span class="kr">End</span><span class="w"> </span><span class="p">{</span><span class="w">

	</span><span class="nv">$End</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Get-Date</span><span class="w">

	</span><span class="n">Write-Verbose</span><span class="w"> </span><span class="s2">"Script finished at </span><span class="si">$(</span><span class="p">(</span><span class="n">Get-Date</span><span class="p">)</span><span class="o">.</span><span class="nf">ToString</span><span class="p">(</span><span class="s1">'yyyy-MM-dd HH:MM:ss'</span><span class="p">)</span><span class="si">)</span><span class="s2">"</span><span class="w">
	</span><span class="n">Write-Verbose</span><span class="w"> </span><span class="s2">"This script took </span><span class="si">$(</span><span class="p">(</span><span class="n">New-TimeSpan</span><span class="w"> </span><span class="nt">-Start</span><span class="w"> </span><span class="nv">$Start</span><span class="w"> </span><span class="nt">-End</span><span class="w"> </span><span class="nv">$End</span><span class="p">)</span><span class="o">.</span><span class="nf">TotalSeconds</span><span class="si">)</span><span class="s2"> seconds to complete"</span><span class="w">

	</span><span class="kr">Return</span><span class="w"> </span><span class="nv">$ReleaseMonth</span><span class="w">
	</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>also what I do, I stick it in my powershell profile (I put the function in the profile, you could stick it in a module you import etc…) and also add this in below it so it displays when I open a session (and also remind myself what todays date is…)</p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">Write-host</span><span class="w"> </span><span class="s2">"Today's date: </span><span class="si">$(</span><span class="n">get-date</span><span class="p">)</span><span class="s2">"
Write-host "</span><span class="n">Current</span><span class="w"> </span><span class="nx">Bloomberg</span><span class="w"> </span><span class="nx">Terminal</span><span class="w"> </span><span class="nx">Release:</span><span class="s2">"
Get-BloombergRelease
</span></code></pre></div></div>

<p>and everytime I open a session it will check and let me know what month’s update is available</p>

<p><img src="/assets/images/WinPowershellBloomy.jpg" alt="WinPoshBloomy" /></p>

<p>I would like it to provide a URL that I could open (I use Windows Terminal so should be doable) , but that is a battle for another day!!</p>

<p>if anyone knows how to improve it, get the download url etc… please let me know as I literally was stumbling, messing around until this worked!!</p>]]></content><author><name>Steven Wight</name><email>PoShYoungTeam@Hotmail.com</email></author><category term="Other" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Powershell Profiles Keepass And Powershellai</title><link href="https://powershellyoungteam.github.io/2023/05/08/PowerShell-Profiles-KeePass-and-PowerShellAI.html" rel="alternate" type="text/html" title="Powershell Profiles Keepass And Powershellai" /><published>2023-05-08T00:00:00+00:00</published><updated>2023-05-08T00:00:00+00:00</updated><id>https://powershellyoungteam.github.io/2023/05/08/PowerShell-Profiles-KeePass-and-PowerShellAI</id><content type="html" xml:base="https://powershellyoungteam.github.io/2023/05/08/PowerShell-Profiles-KeePass-and-PowerShellAI.html"><![CDATA[<p><img src="/assets/images/Hill_Night.png" alt="Screenshot" /></p>

<h1 id="powershell-profiles-keepass-and-powershell-ai-chatgptopenai">PowerShell Profiles, KeePass and PowerShell AI (ChatGPT/OpenAI)</h1>

<p>I was asked over the weekend on Twitter if I could share how I setup my PowerShell profile to pull my OpenAI API key from a KeePass vault so you can start using the PowerShell AI module straight away!</p>

<p>Apologies if this comes across as a notes dump or a user guide written by your IT department, cos that what is basically is!! :)</p>

<p>Right first things first! Let’s download the modules we need!</p>

<blockquote>
  <ul>
    <li>
      <p>Doug Finke’s <strong>PowerShellAI</strong> - <a href="https://github.com/dfinke/PowerShellAI">https://github.com/dfinke/PowerShellAI</a></p>
    </li>
    <li>
      <p>Justin Grote’s <strong>SecretManagement.Keepass</strong> - <a href="https://github.com/JustinGrote/SecretManagement.KeePass">https://github.com/JustinGrote/SecretManagement.KeePass</a></p>
    </li>
  </ul>
</blockquote>

<h2 id="secretmanagementkeepass">SecretManagement.Keepass</h2>

<p>So I already had KeePass, if you don’t then Grab and install KeePass from here <a href="https://keepass.info">https://keepass.info</a> (It’s open source so it’s buckshee !!)</p>

<p>Install KeePass and create a Vault with master password or Keyfile (or both)</p>

<p>You will also need to get your OpenAI API key from <a href="https://beta.openai.com/account/api-keys">https://beta.openai.com/account/api-keys</a> and store it your vault</p>

<p><strong>NOTE:</strong> I found it best just to put your secrets that you want to retrieve via PowerShell in the root of the Vault, hit problems with I put them in a subfolder, so best as per below screenshot.</p>

<p><img src="/assets/images/VaultPicRoot.jpg" alt="VaultPicRoot" /></p>

<p>To install the SecretManagement.Keepass module just download from the PowerShell gallery.</p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">Install-Module</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="nx">SecretManagement.KeePass</span><span class="w">
</span></code></pre></div></div>

<p>Import the module (Import-module SecretManagement.KeePass) and then you need to register the vault so the module knows where and how to access it (below is for a master password only vault, there is a -keyfile argument you can use for keyfiles)</p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">Register-KeepassSecretVault</span><span class="w"> </span><span class="nt">-Path</span><span class="w"> </span><span class="err">&lt;</span><span class="nx">Path</span><span class="w"> </span><span class="nx">to</span><span class="w"> </span><span class="nx">Keepass</span><span class="w"> </span><span class="nx">Vault</span><span class="err">&gt;</span><span class="w"> </span><span class="nt">-UseMasterPassword</span><span class="w">
</span></code></pre></div></div>

<p><img src="/assets/images/registervault.jpg" alt="registerVault" /></p>

<p>You can use Test-SecretVault to check if it worked (will return Boolean) like below</p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">Test-SecretVault</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="err">&lt;</span><span class="nx">Name</span><span class="w"> </span><span class="nx">of</span><span class="w"> </span><span class="nx">vault</span><span class="err">&gt;</span><span class="w">
</span></code></pre></div></div>

<p><img src="/assets/images/Testsecvault.jpg" alt="TestSecVault" /></p>

<h2 id="powershellai">PowerShellAI</h2>

<p>Now we need to install and import PowerShellAI module</p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">Install-Module</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="nx">PowerShellAI</span><span class="w"> 
</span><span class="n">Import-Module</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="nx">PowerShellAI</span><span class="w">
</span></code></pre></div></div>

<p>So now we need to get the API key from the vault and use it for PowerShellAI’s Set-OpenAIKey cmdlet, after that you (Hopefully) should be cooking with gas!!</p>

<p>So for me, I just add this into my profile and when I start a session, I just enter my KeePass Vault password and I am ready to rock and roll!</p>

<p>(don’t need the test-SecretVault, I have left it in there tho..)</p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">import-module</span><span class="w"> </span><span class="nx">PowerShellAI</span><span class="w">
</span><span class="n">Import-Module</span><span class="w"> </span><span class="nx">SecretManagement.KeePass</span><span class="w">


</span><span class="n">test-SecretVault</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="nx">PowerShell</span><span class="w">
</span><span class="nv">$CHatGPTAPIKEY</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Get-Secret</span><span class="w"> </span><span class="nt">-Vault</span><span class="w"> </span><span class="nx">PowerShell</span><span class="w"> </span><span class="nt">-Name</span><span class="w"> </span><span class="nx">ChatGPTAPIKEY</span><span class="w">
</span><span class="n">set-OpenAIKey</span><span class="w"> </span><span class="nv">$CHatGPTAPIKEY</span><span class="w">
</span><span class="n">Get-GPT3Completion</span><span class="w"> </span><span class="s1">'Get me a random quote'</span><span class="w">
</span></code></pre></div></div>

<p><img src="/assets/images/ProfileWorking.jpg" alt="ProfileWorking" /></p>]]></content><author><name>Steven Wight</name><email>PoShYoungTeam@Hotmail.com</email></author><category term="Other" /><summary type="html"><![CDATA[]]></summary></entry></feed>