PowerShell Automation Script for IIS installation and more.

The below script was designed to install IIS with .Net Core Runtime 2.1.x to be used with NOPCommerce. It also enables WinRM (remote management) and changes network settings on the target machine. This is used with Win Server 2019 core to automate deployments with Ansible into AWS.

#
#    The following script changes the Network settings of the Machine
#    disables the firewall, installs IIS and Core Runtime 
#
#Change PS Execution Policy
Set-ExecutionPolicy Bypass -Scope Process -Force

#Enable TLS for Invoke-Webrequest
$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols

######################### VARIABLES #############################################

$tmpdir="c:\temp\"
$newhostname="WIN-SRV-CORE-IIS"
$ipAdd="172.18.85.184"
$sMask="28"   #Ex. 24 = 255.255.255.0
$dGate="172.18.85.177"
######################### FUNCTIONS #############################################

function machineNMchange 
{
    #Change the machine name and reboot    
    $curhostname=hostname
    #$localuser="\Administrator"
    #$localcred=$curhostname+$localuser

    if ($newhostname -ne $curhostname)
    {
        Rename-Computer -ComputerName $curhostname -NewName $newhostname -Force -PassThru    
        # Add -LocalCredential $localcred to the above line if you want to be prompted for credentials, otherwise run as Admin
        # Add -Restart at the end if you want to automatically restart
    }
}

function installCoreRT 
{
    #Note that this installs CoreRuntime 2.1.8
    $url = "https://download.visualstudio.microsoft.com/download/pr/c2b2968d-022d-4889-afd0-b02010813c94/bd315e931f55eecfdaea258cf3dee48e/dotnet-hosting-2.1.8-win.exe"
    $outFile = "dotnet-hosting-2.1.8-win.exe"

    if (Test-Path -Path $tmpdir -PathType Container)
    { 
        Write-Host "$tmpdir already exists" -ForegroundColor Red
    }
    else
    { 
        New-Item -Path $tmpdir  -ItemType directory 
        Write-Host "$tmpdir created" -ForegroundColor Red
    }
    
    Invoke-Webrequest $url -OutFile "$tmpdir$outFile"    
    Start-Process -FilePath $tmpdir$outfile -ArgumentList "/quiet /norestart"
}

function installIIS 
{
    #Install IIS
    # To list all Windows Features: dism /online /Get-Features
    # Get-WindowsOptionalFeature -Online 
    # LIST All IIS FEATURES: 
    # Get-WindowsOptionalFeature -Online | where FeatureName -like 'IIS-*'
    # Source: https://weblog.west-wind.com/posts/2017/May/25/Automating-IIS-Feature-Installation-with-Powershell
    $arr = "IIS-WebServerRole","IIS-WebServer","IIS-CommonHttpFeatures","IIS-HttpErrors","IIS-HttpRedirect",
            "IIS-ApplicationDevelopment","NetFx4Extended-ASPNET45","IIS-NetFxExtensibility45","IIS-HealthAndDiagnostics",
            "IIS-HttpLogging","IIS-LoggingLibraries","IIS-RequestMonitor","IIS-HttpTracing","IIS-Security","IIS-RequestFiltering",
            "IIS-Performance","IIS-WebServerManagementTools","IIS-IIS6ManagementCompatibility","IIS-Metabase",
            "IIS-BasicAuthentication","IIS-WindowsAuthentication","IIS-StaticContent","IIS-DefaultDocument","IIS-WebSockets",
            "IIS-ApplicationInit","IIS-ISAPIExtensions","IIS-ISAPIFilter","IIS-HttpCompressionStatic","IIS-ASPNET45"#,"IIS-ManagementConsole"
            #Enable the last value for GUI servers only, for Core leave out.

    foreach ( $iis_value in $arr)
    {
        Enable-WindowsOptionalFeature -Online -FeatureName $iis_value
    }
}

function setNet ([string]$ip, [string]$sm, [string]$dg)
{
    #Disable Firewall
    Set-NetFirewallProfile -Name Domain,Public,Private -Enabled False

    #Disable IPv6
    Disable-NetAdapterBinding -Name "Ethernet" -ComponentID ms_tcpip6
    
    #Change IP
    Set-NetIPInterface -InterfaceAlias "Ethernet" -Dhcp Disabled
    Remove-NetIPAddress -InterfaceAlias "Ethernet" -Confirm:$false
    New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress $ip -PrefixLength $sm  $ip -DefaultGateway $dg
    #Ex. New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress "172.18.85.184" -PrefixLength "28" -DefaultGateway "172.18.85.177"
    Set-DnsClientServerAddress -InterfaceAlias “Ethernet” -ServerAddresses "172.18.85.177"   

    #Connection-specific DNS Suffix  . : mshome.net
    #Link-local IPv6 Address . . . . . : fe80::29bf:1ecc:e589:3e2c%4
    #IPv4 Address. . . . . . . . . . . : 172.18.85.182
    #Subnet Mask . . . . . . . . . . . : 255.255.255.240
    #Default Gateway . . . . . . . . . : 172.18.85.177

}

########################## MAIN ####################################################
setNet $ipAdd $sMask $dGate
installIIS
installCoreRT
machineNMchange

#Enables Win RM for remote management
winrm quickconfig -force
shutdown /r /t 0

Generate Cyclic Redundancy Check (CRC) Using CertUtil

A CRC is used to detect any changes to the original data/content, the most common reason being accidental data modification and corruption. CRCs are used to validate integrity, to ensure that the data sent is the data received.

It’s quite easy to create a CRC with tools built into the Windows operating system. Open a command prompt window, browse to the location of your file and run the following command:

CertUtil -hashfile <file_name> MD5

By default CertUtil uses SHA1 if the algorithm is not specified, for this example we’re using MD5. CertUtil supports many different algorithm types.

  • MD2
  • MD4
  • MD5
  • SHA1
  • SHA256
  • SHA384
  • SHA512

Once the command has completed successfully CertUtil will output a sequence of numbers and characters, this is the MD5 hash. We will use this hash to validate the integrity of the file once it’s transferred. Once the file is copied we will run the same command and compare the values. If they match the file is valid, if not we know the data was altered. To simplify this process I’ve written a small script in PowerShell that you can leverage.

if ( $(CertUtil -hashfile "<file_name>" MD5) -eq "<hash_from_certutil>" ) { 
  Write-Host "CRC File Integrity Check Passed." -ForegroundColor "Green"

  Write-Host "`nPress any key to exit..."
  $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
  exit 0
}
else {
  Write-Host "CRC File Integrity Check Failed." -ForegroundColor "Red"
  Write-Host "Please re-download file and re-run CRC check."

  Write-Host "`nPress any key to exit..."
  $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
  exit 1
}