PackageManager Part 2: Client Side Setup

Install the NuGet/Chocolatey Provider

With Windows 10 Package Manager almost runs out of the box. If you run Get-PackageProvider from powershell on a fresh Windows 10 instance you will see the out of box providers. There are two more important providers that we will want to setup

  • Nuget – Mainly used to pull code such as Modules from the PSGallery
  • Chocolatey – Build on top of Nuget to pull and install binaries

I expect in the future other plugins will be available as well as being able to create custom providers as explained here


#Install NuGet Provider

Get-Package -ProviderName Nuget -ForceBootstrap

#Install Chocolatey Provider

Get-Package -ProviderName Chocolatey -ForceBootstrap

 

For me, since I have my own internal Repo, I would like a way to install these providers offline. At time of writing it doesn’t appear this is possible so I may have to fall-back to using the chocolatey client until WMF 5.0 and the Chocolatey Provider are officially released.

 

Configure a Package Source


Register-PackageSource -Name InternalRepo `
                       -Location http://svr1/packagemanagerrepo/nuget `
                       -ProviderName chocolatey `
                       -Trusted

 

You should now be able to query your Local Repo for your custom packages. Note for the below I have merely copied some existing packages from Chocolatey.org pending me crafting my own.

PackageManager_2

 

PackageManager Part 1: Setting Up an Internal Repo

Overview

With Powershell 5 comes Package Management which has the potential for becoming the number one tool used when it comes to application deployment. Rather than relying on community written packages from say, Chocolatey, I want to be able to set up my own internal repo to have full control over packages and how they work.

Setting up the NuGet Server

Firstly get a up to date instance of 2012 R2 running and install IIS and ASP .NET 4.5


Install-WindowsFeature -Name Web-Server,Web-Asp-Net45 -Verbose

 

Next get Visual Studio installed and up to date and create a new empty ASP.NET Web Application. For this I will be using Visual Studio 2015 Community Edition which can be downloaded here

  • Start > New Project > ASP.NET Web Application Empty

Now we need to install Nuget.Server via NugetPackage Manager.

  • Right Click References > Manage NuGet Packages > Search for Nuget.Server > Install

If you have trouble finding the package you might want to check your settings. In Options under NuGet Package Manager under Package Sources you should have the link https://api.nuget.org/v3/index.json. (This may vary on between Visual Studio versions)

Once installed you can edit Web.Config to point to a specific directory for Package


<add key="packagePath" value="" />

 

Building the Solution

Now we Need to configure Visual Studio to use IIS instead of its internal IIS Express. To do this:

  • Right Click Project Name > Properties
  • Click Web > Under Servers Select “Local IIS” > Click Create Virtual Directory

Finally the Solution is ready to Build:

  • Right Click Project Name > Build

You should now see your application in IIS and be able to browse to the website.

PackageManager_1

Your Nuget Server is now setup and running. To Test you can drop some previously downloaded .nupkg files into your package path defined in Web.Config. You should be able to browse these at http://localhost/<ProjectName>/nuget.

 

 

IP Address Comparison

Working with IP address in the dotted format can become quite challenging. You can use regex in some cases to identify IP addresses but this is limited.

Simple:


^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$

Accurate:


^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$

You can do more, such as deciding is an IP address falls within a given network, by converting the IP addresses into Decimal. This allows you an easy way to compare.


#Define the Networks you wish to check
$Networks = @(
   '192.168.1.0/8'
   '172.16.1.0/16'
)

#Create Objects for each network that define the IP range as a decimal
$PossibleSubnets = $Networks | ForEach-Object {
   $NetworkAddress = [IPAddress]($_ -split '/')[0]
   $MaskLength = [Byte]($_ -split '/')[1]

   $NetworkAddressBytes = $NetworkAddress.GetAddressBytes()
   [Array]::Reverse($NetworkAddressBytes)
   $RangeLower = [BitConverter]::ToUInt32($NetworkAddressBytes, 0)

   $DecimalMask = [Convert]::ToUInt32(("1" * $MaskLength).PadRight(32, "0"), 2)
   $RangeUpper = $RangeLower -bor -bnot $DecimalMask

   [PSCustomObject]@{
      Network = $_
      NetworkAddress = $NetworkAddress
      MaskLength = $MaskLength
      RangeLower = $RangeLower
      RangeUpper = $RangeUpper
   }
}

 

Given this information you can find which interfaces on your machine are part of which networks.


'localhost' | ForEach-Object {
   Write-Host "Checking $_" -ForegroundColor Yellow
   $ComputerName = $_
   $Interfaces = [Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces()
   $Interfaces | ForEach-Object {
      $Interface = $_
      $IpAddresses = $_.GetIPProperties().UnicastAddresses | Where-Object { $_.Address.ToString() -notin '127.0.0.1', '::1' } | Select-Object -ExpandProperty Address
      $IPAddresses | ForEach-Object {
         #Here we convert the IP addresses found to Decimal for comparison
         $IPAddressBytes = $_.GetAddressBytes()
         [Array]::Reverse($IPAddressBytes)
         $DecimalIPAddress = [BitConverter]::ToUInt32($IPAddressBytes, 0)

         $MySubnets = $PossibleSubnets| Where-Object {$DecimalIPAddress -ge $_.RangeLower -and $DecimalIPAddress -le $_.RangeUpper}

         [PSCustomObject]@{
            ComputerName = $ComputerName
            Interface = $Interface.Name
            Network = $MySubnets.Network
         }
      }
   }
}