Publish a PowerShell module to MyGet in 5 Minutes

I’ve been trying to sell my colleagues on the benefits of PowerShell. Need to interact with Git, do it from PowerShell. Got some repetitive task to perform? PowerShell. I’d like a cup of coffee… seriously write a script to contact your IOT enabled coffee machine and have it ready for you when you get there.

PowerShell All The Things

A buddy was doing some QA testing of a GeoIP lookup service we’ve built. We store IPs as unsigned ints (for speedy Azure table storage row-key lookup) and he needed a quick way to go from integer to 4-octet (1.2.3.4) and back. So we knocked up some PowerShell functions. And then a train of thought took over.

Everyone should hopefully be in the mindset of automating and scripting common tasks. But the benefit is even more powerful if you can share and distribute these things among your friends and colleagues. Maybe you do already. Maybe you paste scripts into Slack. Maybe you have a Github repo that people can grab them from and add import statements to their PSProfile. Here, we’re going to look at bundling our module into a package and deploying it to MyGet so it can be shared and installed by the masses.

Seems like a good idea… right?

Create a PowerShell module

First, I created a new module in my github repo of powershell scripts, creatively named EoinCModule.

The Module directory contains 2 files, the module itself, and a manifest file.

  • EoinCModule
    • EoinCModule.psm1
    • EoinCModule.psd1

A PowerShell module, is a PSM1 file which contains your functions and commandlets. It’s a pretty straight forward PowerShell script file with parameters, comments etc…

The manifest file contains meta-data about the module to describe it during the publish process. To create a template manifest file, you can run the following command in your module directory.

New-ModuleManifest -Path EoinCModule.psd1

The manifest file contains the meta data about your module. At a minimum you’ll need to update it to include

  • Author
  • Description
  • ModuleVersion
  • RootModule (your PSM1 file)
  • FunctionsToExport

Signup to MyGet

Next you’ll need somewhere to publish your package to. MyGet is a public package management site that’s free to sign up for.

I signed up with my gmail account, created a public feed and that’s it.

Publish your Packages

PowerShell 5.0 has integrated publish support to allow you to publish direct to MyGet.

In MyGet, navigate to your profile page and grab your Publisher API key.

Once you have your API Key, run the following commands from your PowerShell prompt to publish your module. (Don’t forget to replace your feed name & api key)

Import-Module PowerShellGet
$PSGalleryPublishUri = 'https://www.myget.org/F/YOUR-FEED-NAME/api/v2/package'
$PSGallerySourceUri = 'https://www.myget.org/F/YOUR-FEED-NAME/api/v2'
$APIKey = 'YOUR-API-KEY'

Register-PSRepository -Name MyGetFeed -SourceLocation $PSGallerySourceUri -PublishLocation $PSGalleryPublishUri
Publish-Module -Path .\YOUR-MODULE-DIRECTORY -NuGetApiKey $APIKey -Repository MyGetFeed -Verbose

That’s it. Your package is published.

Importing your package

Once your package is published you (or anyone else) can import it using the following command.

Install-Module -Name "MODULE-NAME" -RequiredVersion "VERSION" -Repository "REPO-NAME"

Other Bits & Pieces

The process outlined above is pretty trivial, and if you have some module scripts already, getting them published shouldn’t take any longer than 5-10 minutes. I did run into a couple of little issues though. When you generate your manifest, the default template will contain a version number with only a Major.Minor component. In order to publish, the version number must contain at BUILD component as well.

In order to publish you’ll notice a command above to register a PSRepository. This will persist across PowerShell sessions once created. In the above example, I named my repository “MyGetFeed”.

To install my module for example, you would run

Install-Module -Name "EoinCModule" -RequiredVersion "1.0.0" -Repository "MyGetFeed"

To install my module on a different machine, you would first need to register the repository on that machine. e.g.

Import-Module PowerShellGet
Register-PSRepository -Name "eoinc" -SourceLocation "https://www.myget.org/F/eoinc/api/v2"
Install-Module -Name "EoinCModule" -RequiredVersion "1.0.0" -Repository "eoinc"

~Eoin C

Appveyor Continuous Integration and Continuous Delivery

I’ve been maintaining/curating a nuget package for combinatorics over on Github for a while, which I decided to upgrade to .NET Standard over the weekend. I’d noticed that lots of other FOSS projects were up and running on a platform called AppVeyor and had nice little build passing checks on them like this build-passing so I decided to suss it out.

Appveyor is a cloud hosted continuous integration & continuous delivery platform. We use various CI and CD tools at work like Jenkins & Octopus which require a little bit of setting up so I wasn’t really sure what to expect. I certainly wasn’t expecting it to be this easy.

Appveyor Build

Signing up was a matter of creating a free account using my Github credentials (AppVeyor is free for open-source projects/public repos). Then it will prompt you to select the projects you’d like to pull in for CI. I chose the Combinatorics project. Next it figured out from the presence of the Solution (.sln) file, and two unit test projects (MSTest) within, that this was a .NET project and it auto-generated an MSBuild CI job, including automated test runs. Boom! CI Pipeline Done. I’m suitably impressed.

Beyond the vanilla setup it seems quite extensive in its capabilities:

  • You can control which branches/tags and pull requests automatically trigger builds as well as triggering them yourself via web-hook or cron schedule
  • It allows you to customise your entire build pipeline by inserting scripts pre build, pre package, post build, on success, on fail through out for custom jobs execution.
  • You can be notified in a variety of different ways including email, web-hook or slack
  • It has built in transformation processes for AssemblyInfo files so you can tie your build and version info together
  • You can add custom artifacts to include in deployments
  • It supports a whole variety of target deployments for your project artifacts including Azure, FTP, Nuget and more

There’s probably more I haven’t discovered yet. Next job will be to automate the push to Nuget based on commits back to master after Pull Requests are confirmed.

~Eoin C

C# Optional Parameters vs. Method Overloading

I was recently working on some data access/repository code and came across a nice generic repository implemetation for working with EntityFrameworks DataContexts. But when I ran our build through SonarQube, it got itself quite bent out of shape about the following recommendation.

Use the overloading mechanism instead of the optional parameters.

Hmm… Why doesn’t SonarQube like optional parameters. They’ve been a feature of C# since v4.0 and are extremely useful. Consider the following interface.
In the first version, there’s a single method definition that allows the consumer pick and choose what variety of parameters to pass.

In the second verion, you need 8 different method overloads to achieve the same.

So why is SonarQube recommending that latter over the former. Well there’s a few reasons that may not be obvious. These methods are going to be public facing. They are the surface of your API and will be exposed to the world outside your DLL. In my case, my C# Service’s were calling the repository in a different DLL. But not all consumers support Optional Parameters. Java and C++ do not have an equivalent concept available to them. Another reason is that these defaults do not “live” in your DLL per say, but get baked into the call site of the DLL that references them at compile time. So a change in the default values requires the caller application to be recompiled and redeployed rather than just an update of your API library.

Hence why the .NET Frameworks BCL libs all favour Method Overloading over Optional Parameters. But in my case this is internal project code, part of an application stack that gets deployed as a whole.

There’s a benefit to brevity in my code and I’d prefer the implementation to be more concise since I having full control of both the API and Caller as well as the deployment process. So Optional Parameters it is.

If on the other hand you’re writing public API libs for publishing to nuget or you operate in an environment where partial deployments of libraries and components occur, go with Method Overloading.

~Eoin

How not to not get hired

After what seems to a year of solid hiring, we’re finally coming up for air with a full team. We’ve had new people join us at pretty much every level in the company from Intern to Senior, across Design, Development, QA & Project Management. And we’ve seen a pretty significant number of candidates. One thing I’ve noticed is how oftern candidates will do something silly or ill-considered despite an otherwise good application which damaged their chance.

So, rather than providing yet another list of things you should do to get hired, here instead is a list of things you should avoid doing in order to not screw up your chances.

Do not send me a CV more than 3 pages long

It’s not that I don’t care. I just do not have time to read a half page of prose on a role you held 6 years ago in the middle of your 9 page CV. I have 60 other resumés to read. Your CV should have at most 2 pages of content appropriately summarised in lists and short paragraphs. Particularly for more senior candidates, who as a function of time, have more career experience to talk about, you need to be capable of summarising your skills and experience as concisely as possible.

Don’t ignore the question you were asked / Don’t ramble.

I have asked you something very specific. I would like you to answer that question.

  • If you’re not sure or don’t know the answer, that’s fine, we’ll work around it or move on
  • If you would like to subsequently segue the conversation into a related topic, great, but answer the question first
  • If you didn’t understand the question, ask me to clarify

But don’t just go rambling off. And especially don’t do it a second time, if I give you the benefit of the doubt and bring you back on topic. If you continue to ramble off then I’m going to assume you have poor communication skills.

Don’t submit a broken code test

Do not just knock out a code test, hit RUN in your IDE, think “seems to work on my machine” and then throw it over the fence. I have received tests where:

  • Code doesn’t compile
  • Tests don’t run
  • Packages don’t restore
  • Libraries are missing
  • Or it only runs if you have the latest pre-alpha dev build of some unreleased framework installed on your PC

If you are submitting a code test you need to make sure that the person you send it to can run it. When you’re finished I would suggest you do the following check list.

  • Do a clean checkout from your repo and make sure it restores all packages & compiles
  • Compile it from the command line to make sure there are no IDE dependencies or extensions needed
  • Run your unit tests from the command line to make sure they pass
  • Write some deployment/release notes that explain how to compile, install and run your code

Don’t come unprepared?

If you’ve gotten to a face to face interview then you’ve already passed a CV Screen, Phone Interview and Code Test. So don’t trip at the last hurdle by coming to an interview with the intention of winging it.

Bring a copy of your CV with you and know whats in it. If you’ve put something in your CV, expect me to grill you on it. If I feel like you’re bullshitting me, I am going to call you out on it, grill you harder, and tell you it shouldn’t be in your CV.

Be capable of explaining what your current/previous roles and projects are in a simple and concise way. If you have worked in an industry that I am unfamiliar with, then you need to be able to get your explanations across to me without having to educate me on industry subject matter. Assume you may have to take an “ELI5” approach.

Review the basics. Yes I know you are a 10-year senior developer and you can write code day-in-day-out. But I still expect you to be able to talk to me about the basics. What are Solid Principles? What is encapsulation? What is polymorphism? Can you name some software design patterns that aren’t the Factory or Singleton patterns? Have you reviewed any architectural patterns? etc.

Thoughts

Don’t be complacent about getting a new job. Yes, the supply and demand nature of our industry may have tilted things in favour of the candidate of late, but that doesn’t mean that good companies will lower the quality bar when they’re under pressure. If you want a good job in a good company, then you have to assume that they will have good standards which requires an effort from you, the candidate, to land the role you want.

~Eoin C

Xamarin & Azure Notification Hubs

A few weeks back the Azure Dublin user group hosted some of the Microsoft and Xamarins team in Dublin for a half day conference. While the Microsoft & Xamarin teams were there to cover some introductory sessions on using Xamarin, they also invited some industry partners to talk about some other technical topics. I presented a quick 15 minute intro on how to use the Azure Notification Hubs platform for sending push notifications to the various platform specific notification services for each of the major mobile platforms.

Azure Notification Hubs is the Microsoft Azure scaled-out infrastructure for doing multi-platform push-notifications. It provides you with a single single hosted platform which you can configure to relay your push notifications to all the major platform specific push notification services.

Currently, Azure Notification Hubs supports sending notifications to

  • Windows Notification Service (WNS) for Windows Phone & Universal Apps on Windows 8 and Window 10
  • The legacy Microsoft Push Notification Service (MPNS) for older Windows Phone 8 apps
  • Apple Push Notification Service (APNS) for Apple Devices such as IPhones and Macs running iOS and OSX
  • Firebase Cloud Messaging (FCM) and Google Cloud Messaging (GCM) for Android devices & chrome apps
  • Baidu Cloud Push for Android in China
  • Amazon Device Messaging (ADM) for Amazon Kindles

Setup can be a little tricky for the respective platforms. In order to configure Google for example, you’ll need to login to the Google Developer Console and enable the FireBase/Google Cloud Messaging API, recording your API Key. You’ll also need to configure a project under the IAM & Admin Sections and take note of your Project Number which will be used in your source code

Apple’s Push Notification Service on the other hand requires that you generate a CSR which is uploaded to the Apple Developer site. That will allow you to create a Certificate which is in turn uploaded to the Azure Notification Hub configuration.

Once you’ve configured the various platform notification services in Azure, you can start pushing notifications out to various subsets of your user base. Notification Hub clients support connecting with Tag configurations. This allows you to dynamically tag your client base by device, demographic, specific user or some other categorisation and then targets those subsets of users

You’ll find some demo code to get you started in our demo repository of Source Code on Github and a copy of the presentation slides from the demostration below

~Eoin C