CISPowerShell.psm1

<#
.SYNOPSIS
    Download Putty
 
.DESCRIPTION
    Download the x64 or x86 version of the latest version of Putty to a
    specified file path location
 
.EXAMPLE
    Download-Putty -FilePath C:\
     
    This example will determine if you need the x86 or x64 version of Putty
    and save the executable file to c:\putty.exe
 
.EXAMPLE
    Save-d00mPutty -FilePath C:\users\Me\NewFolder
 
    This example will determine if you need the x86 or x64 version of Putty
    and save the executable file to c:\users\Me\NewFolder. If NewFolder doesn't
    exist, the cmdlet will create the folder for you
#>

function Download-Putty
{
    [cmdletbinding()]
    param
    (
        [parameter(Mandatory = $true)]
        [string]$FilePath
    )

    begin
    {
        $timer = New-Object -TypeName System.Diagnostics.StopWatch
        $cmdletName = $PSCmdlet.MyInvocation.MyCommand.Name
        Write-Verbose -Message ('{0} : Begin execution : {1}' -f $cmdletName, (Get-Date))
        $timer.Start()
    }

    process
    {
        try
        {
            if (Test-Connection google.com -Count 1)
            {
                Write-Verbose -Message ('{0} : Creating destination filepath : {1}' -f $cmdletName, $FilePath)
                If (!(Test-Path -Path $FilePath))
                {
                    New-Item -Path $FilePath -ItemType Directory -Force | Out-Null
                    Write-Verbose -Message ('{0} : Created destination filepath complete' -f $cmdletName)
                }
                Write-Verbose -Message ('{0} : Detecting operating system architecture' -f $cmdletName)
                $uri = switch ((Get-WmiObject -Class Win32_OperatingSystem -Property OSArchitecture).OSArchitecture)
                {
                    '32-bit'
                    {
                        Write-Verbose -Message ('{0} : Detected x86 operating system' -f $cmdletName)
                        'https://the.earth.li/~sgtatham/putty/latest/w32/putty.exe'
                    }

                    '64-bit'
                    {
                        Write-Verbose -Message ('{0} : Detected x64 operating system' -f $cmdletName)
                        'https://the.earth.li/~sgtatham/putty/latest/w64/putty.exe'
                    }
                }
                Write-Verbose -Message ('{0} : Download URL : {1}' -f $cmdletName, $uri)
                Invoke-WebRequest -Uri $uri -OutFile (Join-Path -Path $FilePath -ChildPath 'putty.exe')
                Write-Verbose -Message ('{0} : Download complete' -f $cmdletName)
                '{0} : Download complete. FilePath : {1}\putty.exe' -f $cmdletName, $FilePath | Write-Output
            }
            else
            {
                'No access to internet! Unable to download Putty!' | Write-Warning
            }
        }
        catch
        {
            throw
        }
    }

    end
    {
        $timer.Stop()
        Write-Verbose -Message ('{0} : End execution' -f $cmdletName)
        Write-Verbose -Message ('Total execution time: {0} ms' -f $timer.Elapsed.TotalMilliseconds)
    }
}


<#
.SYNOPSIS
    Get a computer's public IP address
 
.DESCRIPTION
    Retrieve a computer's public IP address by using Amazon's CheckIP REST service
 
.EXAMPLE
    Get-PublicIP
     
    This example will retrieve the local machine's public IP address
 
.EXAMPLE
    Get-PublicIP -ComputerName Computer1, Computer2, Computer3
 
    This example will retrieve the specified computers public IP addresses using
    default credentials
 
.EXAMPLE
    Get-PublicIP -ComputerName (Get-Content c:\list.txt) -Credential (Get-Credential)
 
    This example will retrieve public IP addresses for the list of computer names
    in the file c:\list.txt (one computername per line) using the specified credentials
#>

function Get-PublicIP
{
    [cmdletbinding()]
    param
    (
        [parameter(ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true)]
        [string[]]$ComputerName = $env:COMPUTERNAME,
        
        [parameter()]
        [pscredential]$Credential   
    )

    begin
    {
        $timer = New-Object -TypeName System.Diagnostics.StopWatch
        $cmdletName = $PSCmdlet.MyInvocation.MyCommand.Name
        Write-Verbose -Message ('{0} : Begin execution : {1}' -f $cmdletName, (Get-Date))
        $timer.Start()
    }

    process
    {
        foreach ($computer in $ComputerName)
        {
            Write-Verbose -Message ('{0} : {1} : Begin execution' -f $cmdletName, $computer)
            $sessionParams = @{ComputerName = $computer
                               ErrorAction  = 'Stop'}
            if ($Credential -ne $null)
            {
                $sessionParams.Add('Credential', $Credential)
                Write-Verbose -Message ('{0} : {1} : Using supplied credentials' -f $cmdletName, $computer)
            }
            else
            {
                Write-Verbose -Message ('{0} : {1} : Using default credentials' -f $cmdletName, $computer)
            }
            $session = $null
            $session = New-PSSession @sessionParams
            if ($session)
            {
                $ip = $null
                $ip = Invoke-Command -Session $session -ScriptBlock {
                    Invoke-RestMethod -Uri http://checkip.amazonaws.com
                }
                $props = @{ComputerName = [string]$computer
                           PublicIP     = [ipaddress]$ip.Trim()}
                New-Object -TypeName System.Management.Automation.PSObject -Property $props | Write-Output
            }
            else
            {
                '{0} : {1} : Unable to create PSSession. If not supplied, try including the -Credential parameter' -f $cmdletName, $computer | Write-Warning
            }
        }
    }

    end
    {
        $timer.Stop()
        Write-Verbose -Message ('{0} : End execution' -f $cmdletName)
        Write-Verbose -Message ('Total execution time: {0} ms' -f $timer.Elapsed.TotalMilliseconds)
    }
}


<#
.SYNOPSIS
    Change a Server Core instance's default shell from CMD.exe to PowerShell.exe
 
.DESCRIPTION
    Set registry key to specify PowerShell as default shell
    HKLM:\Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Shell = "PowerShell.exe -NoExit"
 
    * ONLY APPLICABLE TO SERVER CORE INSTALLATIONS *
 
.EXAMPLE
    Set-PowerShellDefaultShell
 
    This example sets PowerShell as the default shell on the local machine using default
    credentials and then warns the user that the local machine must still be rebooted for
    the changes to take effect
 
.EXAMPLE
    Set-PowerShellDefaultShell -ComputerName Server1, Server2 -Restart
 
    This example sets PowerShell as the default shell on the specified computer names (Server1
    and Server2) using default credentials and then reboots the computers automatically when
    complete.
 
.EXAMPLE
    Set-PowerShellDefaultshell -ComputerName (Get-Content c:\list.txt) -Credential (Get-Credential) -Restart
 
    This example sets Powershell as the default shell on the specified computer names read
    from the file specified (1 computername per line) using the supplied credentials of
    Get-Credential and then reboots the computers automatically when complete
#>

function Set-PowerShellDefaultShell
{
    [cmdletbinding()]
    param
    (
        [parameter(ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true)]
        [string[]]$ComputerName = $env:COMPUTERNAME,
        
        [parameter()]
        [pscredential]$Credential,

        [parameter()]
        [switch]$Restart
    )

    begin
    {
        $timer = New-Object -TypeName System.Diagnostics.StopWatch
        $cmdletName = $PSCmdlet.MyInvocation.MyCommand.Name
        Write-Verbose -Message ('{0} : Begin execution : {1}' -f $cmdletName, (Get-Date))
        $timer.Start()

        $keyPath = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\winlogon'
        Write-Verbose -Message ('{0} : KeyPath : {1}' -f $cmdletName, $keyPath)
    }

    process
    {
        foreach ($computer in $ComputerName)
        {
            Write-Verbose -Message ('{0} : {1} : Begin execution' -f $cmdletName, $computer)
            $sessionParams = @{ComputerName = $computer
                               ErrorAction  = 'Stop'}
            if ($Credential -ne $null)
            {
                $sessionParams.Add('Credential', $Credential)
                Write-Verbose -Message ('{0} : {1} : Using supplied credentials' -f $cmdletName, $computer)
            }
            else
            {
                Write-Verbose -Message ('{0} : {1} : Using default credentials' -f $cmdletName, $computer)
            }
            $session = $null
            $session = New-PSSession @sessionParams
            if ($session)
            {
                try
                {
                    $result = Invoke-Command -Session $sessionParams -ArgumentList $keyPath, $Restart -ScriptBlock {
                        try
                        {
                            Set-ItemProperty -Path $args[0] -Name 'Shell' -Value 'PowerShell.exe -NoExit' -Force
                            $true | Write-Output
                            if ($args[1])
                            {
                                Restart-Computer -Force
                            }
                        }
                        catch
                        {
                            throw
                        }
                    }
                    New-Object -TypeName System.Management.Automation.PSCustomObject -Property @{ComputerName = $computer
                                                                                                 Result       = $result} |
                        Write-Output
                    if (!$Restart)
                    {
                        '{0} : {1} : Successfully set PowerShell as default shell - reboot is required to make setting active' -f $cmdletName, $computer | Write-Warning
                    }
                }
                catch
                {
                    throw
                }
            }
            else
            {
                '{0} : {1} : Unable to create PSSession' -f $cmdletName, $computer | Write-Warning
                if (!$Credential)
                {
                    'Try including the -Credential parameter!' | Write-Warning
                }
            }
        }
    }

    end
    {
        $timer.Stop()
        Write-Verbose -Message ('{0} : End execution' -f $cmdletName)
        Write-Verbose -Message ('Total execution time: {0} ms' -f $timer.Elapsed.TotalMilliseconds)
    }
}