<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>programming on Cory Knox</title>
    <link>https://coryknox.dev/categories/programming/</link>
    <description>Recent content in programming on Cory Knox</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Mon, 14 Jan 2019 00:00:00 +0000</lastBuildDate><atom:link href="https://coryknox.dev/categories/programming/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Everything you didn&#39;t know you didn&#39;t know about PSModuleDevelopment</title>
      <link>https://coryknox.dev/posts/2019/module-development/</link>
      <pubDate>Mon, 14 Jan 2019 00:00:00 +0000</pubDate>
      
      <guid>https://coryknox.dev/posts/2019/module-development/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://coryknox.dev/img/posts/ModuleDevelopment.png&#34; alt=&#34;wordcloud&#34;&gt;&lt;/p&gt;
&lt;p&gt;Late in 2018, I had the distinct pleasure of spending a few hours with &lt;a href=&#34;https://twitter.com/FredWeinmann&#34;&gt;@FredWeinmann&lt;/a&gt;. We spent the time fixing up my PSCUCM Module (Available from the &lt;a href=&#34;https://www.powershellgallery.com/packages/PSCUCM&#34;&gt;PowerShell Gallery&lt;/a&gt; and &lt;a href=&#34;https://github.com/corbob/PSCUCM&#34;&gt;GitHub&lt;/a&gt;). During this session we went through a number of commands and setups utilizing his PSModuleDevelopment module and PSFramework. What will ensue is a multi-part series on Developing PowerShell Modules using PSFramework and PSModuleDevelopment.&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;And so, without further ado, I present part 1:&lt;/p&gt;
&lt;h1 id=&#34;setting-up-pre-requisites&#34;&gt;Setting up pre-requisites &lt;a href=&#34;#setting-up-pre-requisites&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;We&amp;rsquo;re going to be using modules from the &lt;a href=&#34;https://github.com/PowershellFrameworkCollective&#34;&gt;Powershell Framework Collective&lt;/a&gt;. Specifically: &lt;code&gt;PSFramework&lt;/code&gt; and &lt;code&gt;PSModuleDevelopment&lt;/code&gt;. However, I recommend looking at &lt;code&gt;PSUtil&lt;/code&gt; as it contains some great functions that make working in PowerShell even more delightful.&lt;/p&gt;
&lt;p&gt;Due to the way the PowerShell Gallery works you can install both modules with a single command: &lt;code&gt;Install-Module PSModuleDevelopment -Scope CurrentUser&lt;/code&gt;&lt;/p&gt;
&lt;h1 id=&#34;setting-up-directory-structures&#34;&gt;Setting up directory structures &lt;a href=&#34;#setting-up-directory-structures&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;With our modules installed, the first thing we need to do is setup our directory structures. To build a module prepared for Azure DevOps (formerly &lt;!-- raw HTML omitted --&gt;VSTS&lt;!-- raw HTML omitted --&gt;), we will use the &lt;code&gt;PSFProject&lt;/code&gt; template that comes with &lt;code&gt;PSModuleDevelopment&lt;/code&gt;. I encourage you to explore the various templates to see what&amp;rsquo;s available.&lt;/p&gt;
&lt;p&gt;To get started we run the following code: &lt;code&gt;Invoke-PSMDTemplate PSFProject&lt;/code&gt; This will prompt for a &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt;, provide these and the function will establish the scaffolding for our project. The directory layout for a module called DemoModule will be something like the below:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;DemoModule
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── build
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── filesAfter.txt
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── filesBefore.txt
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── vsts-build.ps1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── vsts-prerequisites.ps1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   └── vsts-validate.ps1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── install.ps1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── library
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   └── DemoModule
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│       ├── DemoModule
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│       │   ├── Class1.cs
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│       │   └── DemoModule.csproj
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│       └── DemoModule.sln
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── LICENSE
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── DemoModule
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── bin
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │   └── readme.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── en-us
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │   └── about_DemoModule.help.txt
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── functions
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │   └── readme.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── internal
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │   ├── configurations
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │   │   ├── configuration.ps1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │   │   └── readme.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │   ├── functions
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │   │   └── readme.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │   ├── scripts
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │   │   ├── license.ps1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │   │   ├── postimport.ps1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │   │   └── preimport.ps1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │   └── tepp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │       ├── assignment.ps1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │       ├── example.tepp.ps1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │       └── readme.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── DemoModule.psd1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── DemoModule.psm1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── readme.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── tests
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │   ├── functions
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │   │   └── readme.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │   ├── general
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │   │   ├── FileIntegrity.Exceptions.ps1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │   │   ├── FileIntegrity.Tests.ps1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │   │   ├── Help.Exceptions.ps1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │   │   ├── Help.Tests.ps1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │   │   ├── Manifest.Tests.ps1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │   │   └── PSScriptAnalyzer.Tests.ps1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │   ├── pester.ps1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   │   └── readme.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   └── xml
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│       ├── DemoModule.Format.ps1xml
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│       ├── DemoModule.Types.ps1xml
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│       └── readme.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;└── README.md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;directory-structure-overview&#34;&gt;Directory structure overview &lt;a href=&#34;#directory-structure-overview&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;First thing we will notice is that it created a directory titled DemoModule. This is clearly where we store our module and the related item. Of note is the numerous readme files present in the template. These will give you an overview of the areas that they are found so you can take further advantage of them. What follows is a sumarization in my own words what these directories are for, or at least what I use them for.&lt;/p&gt;
&lt;h2 id=&#34;build&#34;&gt;build &lt;a href=&#34;#build&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Within the DemoModule directory we have the build directory. This contains the scripts that are all preconfigured for use within an Azure DevOps pipeline. These will be covered in more depth in a coming installment of this series.&lt;/p&gt;
&lt;h2 id=&#34;library&#34;&gt;library &lt;a href=&#34;#library&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Next is the library. This contains the files and directories needed for a C# project that will result in a DLL. If we use this, it will automatically put he DLL into the appropriate places for the rest of our template to take advantage of. This is an area of the template I have not looked at, nor have I taken advantage of &lt;em&gt;yet&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id=&#34;demomodule&#34;&gt;DemoModule &lt;a href=&#34;#demomodule&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Up next is the DemoModule directory. This directory contains all of the files to actually make our module a module. This includes the manifest file, and the module file itself.&lt;/p&gt;
&lt;h3 id=&#34;demomodulebin&#34;&gt;DemoModule/bin &lt;a href=&#34;#demomodulebin&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The bin directory contains any binary data that is part of your module.&lt;/p&gt;
&lt;h3 id=&#34;demomoduleen-us&#34;&gt;DemoModule/en-us &lt;a href=&#34;#demomoduleen-us&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;This is your Engligh US based help files. I haven&amp;rsquo;t made use of this yet, I&amp;rsquo;ve been using Comment Based Help&amp;hellip; So you&amp;rsquo;re on your own for this one ¯_(ツ)_/¯&lt;/p&gt;
&lt;h3 id=&#34;demomodulefunctions&#34;&gt;DemoModule/functions &lt;a href=&#34;#demomodulefunctions&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Your public facing functions should be placed in the functions directory. The build scripts will expect this, and will check that you&amp;rsquo;re exporting every function that&amp;rsquo;s in here.&lt;/p&gt;
&lt;h3 id=&#34;demomoduleinternal&#34;&gt;DemoModule/internal &lt;a href=&#34;#demomoduleinternal&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Internal will contain the&amp;hellip; Wait for it&amp;hellip; internal components of our module. This includes configuration, functions, internal scripts, and tab expansion settings (tepp).&lt;/p&gt;
&lt;h4 id=&#34;demomoduleinternalconfigurations&#34;&gt;DemoModule/internal/configurations &lt;a href=&#34;#demomoduleinternalconfigurations&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Configurations will house the configurations for your module. In a PSFramework module you will likely put your PSFConfig initializations in here.&lt;/p&gt;
&lt;h4 id=&#34;demomoduleinternalfunctions&#34;&gt;DemoModule/internal/functions &lt;a href=&#34;#demomoduleinternalfunctions&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Functions will house the internal functions. These are typically functions that do make things easier for your when developing the module, but don&amp;rsquo;t need to extend beyond the module. Examples may be consistently fetching certain data, or creating objects consistently. Basically anything that you will need to do multiple times but the end user won&amp;rsquo;t need to do should go in this directory. These functions should also follow best practices and follow the Verb-Noun principal with approved verbs.&lt;/p&gt;
&lt;h4 id=&#34;demomoduleinternalscripts&#34;&gt;DemoModule/internal/scripts &lt;a href=&#34;#demomoduleinternalscripts&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;The default scripts are: &lt;code&gt;license.ps1&lt;/code&gt;, &lt;code&gt;preimport.ps1&lt;/code&gt;, and &lt;code&gt;postimport.ps1&lt;/code&gt;. These files contain your license (default is MIT license), any commands that should be processed before your module is imported (perhaps some verification of module or application installations?), and the commands to be processed after your module is imported. By default the preimport.ps1 is effectively empty. The important file in the default scaffolding is the &lt;code&gt;postimport.ps1&lt;/code&gt; file. This file will import all of your configurations, your tab expansion, and finally your license.&lt;/p&gt;
&lt;h4 id=&#34;demomoduleinternaltepp&#34;&gt;DemoModule/internal/tepp &lt;a href=&#34;#demomoduleinternaltepp&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;At last we reach the tepp directory&amp;hellip; tepp stands for Tab Expansion Plus Plus. This is the module that first brough tab expansion to PowerShell. PSFramework includes functions for registering these tab expansions that work by default in Windows 10 running PowerShell 5, as well as PowerShell 6 on all Operating Systems that I&amp;rsquo;ve tested it on. The benefit of registering tab expansion over using a ValidateSet is that a ValidateSet requires that the parameter match the set, while a tepp registered set is only some of the possible entries. For instance, in creating a custom wrapper for PSCUCM&amp;rsquo;s &lt;code&gt;New-Phone&lt;/code&gt; function, I could register tab expansions for the phones that we have. This allows new phones to be added without the need to immediately update the tepp as you could just specify the new phone. A ValidateSet would require that we update the set prior to trying to use the new phone with the function.&lt;/p&gt;
&lt;h3 id=&#34;demomoduletests&#34;&gt;DemoModule/tests &lt;a href=&#34;#demomoduletests&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The tests directory. This contains all the tests that you&amp;rsquo;re obviously going to include with your module&amp;hellip;&lt;/p&gt;
&lt;h4 id=&#34;demomoduletestsfunctions&#34;&gt;DemoModule/tests/functions &lt;a href=&#34;#demomoduletestsfunctions&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;The functions directory within tests is for your modules functions. You can divide this directory up as you see fit. If you&amp;rsquo;re going to test your internal functions (and why wouldn&amp;rsquo;t you?), then you might want a &lt;code&gt;internal&lt;/code&gt; directory. My recommendation would be to follow the structure that you use for your public functions, and to have a test file for each function file.&lt;/p&gt;
&lt;h4 id=&#34;demomoduletestsgeneral&#34;&gt;DemoModule/tests/general &lt;a href=&#34;#demomoduletestsgeneral&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;The general directory contains the tests included with the scaffolding. These tests will check &lt;em&gt;all&lt;/em&gt; of your functions for some form of help for &lt;em&gt;all&lt;/em&gt; parameters. It will check the Examples for a description (if using comment based help, the description comes after a blank line following the example).&lt;/p&gt;
&lt;h3 id=&#34;demomodulexml&#34;&gt;DemoModule/xml &lt;a href=&#34;#demomodulexml&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The xml directory contains the Type and Format Definitions for your module. The PSModuleDevelopment includes some helpful functions for creating these xml files so you don&amp;rsquo;t need to work with them by hand. If you have need for some of these files, I highly recommend investigating the readme file within as it does an excellent job of describing the process.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion &lt;a href=&#34;#conclusion&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;Now that we&amp;rsquo;ve gone over the basics of getting started, you can go out and get your own modules started. Stay tuned for part 2 where we&amp;rsquo;ll take our next step in the journey.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>A Foray into vscode-powershell</title>
      <link>https://coryknox.dev/posts/2018/foray-into-vscode-powershell/</link>
      <pubDate>Mon, 03 Sep 2018 00:00:00 +0000</pubDate>
      
      <guid>https://coryknox.dev/posts/2018/foray-into-vscode-powershell/</guid>
      <description>&lt;p&gt;This is a foray into getting started with the vscode-powershell extension. In particular noting some of the perhaps less obvious things I needed to do in order to get it to build on Ubuntu 18.04.&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;First thing you&amp;rsquo;ll need to do of course is to fork the repository. There are two repositories that we want to fork to our github account: &lt;a href=&#34;https://github.com/PowerShell/PowerShellEditorServices&#34;&gt;PowerShellEditorService&lt;/a&gt; and &lt;a href=&#34;https://github.com/PowerShell/vscode-powershell&#34;&gt;vscode-powershell&lt;/a&gt;. Once you&amp;rsquo;ve forked them (and perhaps made hours of work that Tiler and Rob keep harrassing you as not being good enough&amp;hellip;) you need to clone them to your local machine. I highly recommend keeping them side by side and so I clone them into a repos directory. On my Windows machine all of my git repos are stored at &lt;code&gt;C:\repos\&lt;/code&gt; on my fresh install of Ubuntu Linux 18.04 they&amp;rsquo;re stored at &lt;code&gt;~/git/&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&#34;system-software-to-install&#34;&gt;System software to install &lt;a href=&#34;#system-software-to-install&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;Now after freshly installing Ubuntu 18.04, I have installed the following software on top of the base:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;PowerShell-Preview - PowerShell 6.1 is in Release Candidate, and is the only &amp;ldquo;Supported&amp;rdquo; version for Ubuntu 18.04&lt;/li&gt;
&lt;li&gt;npm - Not entirely sure if I installed this one, or if it&amp;rsquo;s just installed as part of Ubuntu&amp;hellip; It&amp;rsquo;s definitely installed though.&lt;/li&gt;
&lt;li&gt;VS Code Insiders&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Once this is installed, and the repos are cloned. I opened vscode-powershell in vscode-insiders. I then selected &lt;code&gt;Debug &amp;gt; Start Debugging&lt;/code&gt; This greeted me with the message: &amp;ldquo;The preLaunchTask &amp;lsquo;BuildAll&amp;rsquo; terminated with exit code 1.&amp;rdquo; Clearly we&amp;rsquo;re missing some pre-requisites&amp;hellip; Looking in the terminal we see:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;gt; Executing task: Invoke-Build BuildAll &amp;lt;

execvp(3) failed.: No such file or directory
The terminal process terminated with exit code: 1

Terminal will be reused by tasks, press any key to close it.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This initially felt like we were missing InvokeBuild from the PowerShell Gallery. Unfortunately, after installing that, the error is still present. The build appears to work if we do Invoke-Build from pwsh-preview.&lt;/p&gt;
&lt;p&gt;It turns out that this is the trick here. We&amp;rsquo;re using a preview build of pwsh on Ubuntu 18.04, because that is what&amp;rsquo;s available. To resolve this, we can simply create a symlink from pwsh to pwsh-preview&amp;hellip; This may need to be resolved once pwsh 6.1 leaves Release Candidate, or the installation of pwsh may resolve it for us. To create the symlink: &lt;code&gt;sudo ln -s /usr/bin/pwsh-preview /usr/bin/pwsh&lt;/code&gt;. Once this symlink is created, debugging of both vscode-powershell and PowerShellEditorServices seems to go off without a hitch.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion &lt;a href=&#34;#conclusion&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Once getting over the hurdle of pwsh not being available outside of a preview on Ubuntu 18.04, getting vscode-powershell and PowerShellEditorServices development going in Ubuntu 18.04 is actually really easy, and dare I say may be even easier than doing the same thing on Windows 10&amp;hellip;&lt;/p&gt;
&lt;p&gt;I did note while investigating the pwsh-preview issue that there are already documents that may provide more information (and will at least be more up to date than this document) here: &lt;a href=&#34;https://github.com/PowerShell/vscode-powershell/blob/master/docs/development.md&#34;&gt;vscode-powershell Development Document&lt;/a&gt; and here: &lt;a href=&#34;https://github.com/PowerShell/PowerShellEditorServices#development&#34;&gt;PowerShellEditorServices ReadMe&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Azure Functions FTW - Using Azure Functions to schedule GitHub Pages posts</title>
      <link>https://coryknox.dev/posts/2018/azure-functions-ftw/</link>
      <pubDate>Wed, 29 Aug 2018 00:00:00 +0000</pubDate>
      
      <guid>https://coryknox.dev/posts/2018/azure-functions-ftw/</guid>
      <description>&lt;p&gt;If you&amp;rsquo;re reading this&amp;hellip; And it&amp;rsquo;s after August 29th 2018 at 9 AM PDT&amp;hellip; Then that means it worked. I mean I know it works because this isn&amp;rsquo;t the first post of it&amp;rsquo;s kind, but it&amp;rsquo;s the first I&amp;rsquo;m actually going to keep up.&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;It all started when I was discussing having finally setup this blog on Twitter. Someone asked if I could schedule blog posts. At the time I didn&amp;rsquo;t know if it was possible, but a simple web search found the answer over here: &lt;a href=&#34;https://evertpot.com/scheduling-github-pages-lamdbas/&#34;&gt;Scheduling posts on Github pages with AWS lambda functions by: Evert Pot&lt;/a&gt; Of course, this is fine and dandy if you already have AWS. But! What if you have Azure? Could you do something similar with it?&lt;/p&gt;
&lt;h2 id=&#34;setup&#34;&gt;Setup &lt;a href=&#34;#setup&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;From what I could make of AWS lambda functions they are somewhat analogous to Azure Functions. It appears that the billing is somewhat similar, and different as we&amp;rsquo;ll see. First we need to setup an Azure Function App within our Azure account. I&amp;rsquo;ll leave that as an exercise for the user, but hit me up in the comments or on Twitter if you need some pointers.&lt;/p&gt;
&lt;p&gt;Once I had the Azure Function App setup, I attempted to make a javascript function following the code provided by Evert. Unfortunately it would seem some of the conventions used don&amp;rsquo;t work with Azure Functions (although it seems perhaps they do, you just need to turn on a preview of v2 or something of the like). The main thing I was tripping on was that await and async didn&amp;rsquo;t seem to be available. Further, no matter what I did, the query was always returning undefined. Instead of fight with a language I understand, but in a runspace I do not understand, I started investigating if it could be done with PowerShell. Looking at the github API documentation, it looks fairly straight forward. You send a request to the API, and it either returns success, or it returns 404.&lt;/p&gt;
&lt;p&gt;After determining that we could do this with an Invoke-RestMethod in PowerShell, the next step was to setup the PowerShell function. Within the Function App you want to enable Experimental Language support and then add a new timer trigger. Like Evert, I have mine set to fire every hour on the hour. Once we&amp;rsquo;ve created the function, we need to populate it with the code.&lt;/p&gt;
&lt;h2 id=&#34;code&#34;&gt;Code &lt;a href=&#34;#code&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The below is not fully tested in production. As with most things, I got the command working and have left it as is for my setup. However, for this blog post we need it to be a tad prettier&amp;hellip; so I have moved the username and token into variables and expanded the command from irm. I&amp;rsquo;m open to Pull Requests should this not function properly.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$Token&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;YourGitHubToken&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$Username&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;YourGitHubUsername&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$InvokeRestMethodSplat&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;Uri&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://api.github.com/repos/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$Username&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$Username&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;.github.io/pages/builds&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;Method&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Post&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;Headers&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;Authorization&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;token &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$Token&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;Accept&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;application/vnd.github.mister-fantastic-preview+json&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;Invoke-RestMethod&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;@InvokeRestMethodSplat&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;break-it-on-down&#34;&gt;Break it on down &lt;a href=&#34;#break-it-on-down&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;I&amp;rsquo;m trying not to reproduce everything that Evert, but the basic breakdown as listed on his article:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a &lt;a href=&#34;https://github.com/settings/tokens&#34;&gt;Personal Access Token&lt;/a&gt; on GitHub.&lt;/li&gt;
&lt;li&gt;Make sure you give it at least the &lt;code&gt;repo&lt;/code&gt; and &lt;code&gt;user&lt;/code&gt; privileges.&lt;/li&gt;
&lt;li&gt;Make sure you add &lt;code&gt;future: false&lt;/code&gt; to your &lt;code&gt;_config.yaml&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Write a blog post, and set the &lt;code&gt;date&lt;/code&gt; to some point in the future.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Once we&amp;rsquo;ve setup the Token, and set our &lt;code&gt;_config.yaml&lt;/code&gt; properly, we can go ahead with the function. If we check out the GitHub &lt;a href=&#34;https://developer.github.com/v3/repos/pages/&#34;&gt;API documentation&lt;/a&gt; we&amp;rsquo;ll see that we can just make a simple web request to the API endpoint with our token and voila it initiates a build.&lt;/p&gt;
&lt;h2 id=&#34;costs&#34;&gt;Costs &lt;a href=&#34;#costs&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;I told you I&amp;rsquo;d get to costs&amp;hellip; Unfortunately, it is looking like this isn&amp;rsquo;t quite as cheap as AWS lambda functions. I haven&amp;rsquo;t gone a full billing cycle, but at 9 days in, this is showing as costing $0.01 CAD so far. This isn&amp;rsquo;t due to runtime of the function though. This is due entirely to the underlying storage costs. Apparently we need to pay for somewhere to store our function. And really, if it&amp;rsquo;s going to cost us a few pennies a month, it&amp;rsquo;s close enough to free.&lt;/p&gt;
&lt;h2 id=&#34;caveats&#34;&gt;Caveats &lt;a href=&#34;#caveats&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;One thing to be aware of, if you use the RSS feed. Every time this function fires, the date at the top of the RSS file updates (this also makes a convenient place to check if it&amp;rsquo;s running). I don&amp;rsquo;t believe this to be an issue for anything, but perhaps if you use a feed reader you could let me know if you see duplicate posts or anything strange.&lt;/p&gt;
&lt;h2 id=&#34;next-stepsfollow-up&#34;&gt;Next steps/Follow-up &lt;a href=&#34;#next-stepsfollow-up&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;I will try to remind myself to update this post when my Azure month rolls over in Mid September. I fully expect that costs shouldn&amp;rsquo;t change much.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>So you want to make a VS Code extension</title>
      <link>https://coryknox.dev/posts/2018/vscode-extensioning/</link>
      <pubDate>Tue, 03 Jul 2018 00:00:00 +0000</pubDate>
      
      <guid>https://coryknox.dev/posts/2018/vscode-extensioning/</guid>
      <description>&lt;p&gt;So, you have this great idea for a VS Code extension? But perhaps you&amp;rsquo;re thinking &amp;ldquo;where do I start?&amp;rdquo; Well, fear not! for I have written this post to tell you the answer!&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;Oh? Were you expecting me to have the answer? Well, you see the truth is I have no idea. I just took some code, put some other code in it, and it worked (well sorta).&lt;/p&gt;
&lt;p&gt;But for reals: Decide if you want to use TypeScript or JavaScript (I picked TypeScript because all the samples were in TypeScript). Then take a look at &lt;a href=&#34;https://code.visualstudio.com/docs/extensions/example-hello-world&#34;&gt;https://code.visualstudio.com/docs/extensions/example-hello-world&lt;/a&gt; to get your first example done.&lt;/p&gt;
&lt;p&gt;If like me you have little experience with TypeScript, it is worth reading through this one to try and understand what it is doing. Also take a look at the examples: &lt;a href=&#34;https://code.visualstudio.com/docs/extensions/example-hello-world&#34;&gt;https://github.com/Microsoft/vscode-extension-samples&lt;/a&gt; I went here to look at the tree-view-sample for the one I&amp;rsquo;m working on.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
