CISPowerShell.psm1
<#
.SYNOPSIS Save Putty .DESCRIPTION Save the x64 or x86 version of the latest version of Putty to a specified file path location .EXAMPLE Save-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-Putty -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 Save-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) { try { 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 } } 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 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()] [alias('Reboot')] [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) } } <# .SYNOPSIS Get a computers uptime .DESCRIPTION Calculate a computer's uptime by retrieving the LastBootUpTime property from the Win32 OperatingSystem WMI class and subtracting that from the current date and time. .EXAMPLE Get-UpTime This example retrieves the local machine's uptime using default credentials .EXAMPLE Get-UpTime -ComputerName Server1, Server2 -Restart This example retrieves the specified computer's uptime using default credentials .EXAMPLE Get-UpTime -ComputerName (Get-Content c:\list.txt) -Credential (Get-Credential) This example retrieves the computer names found in the file (one computer name per line) uptime using the specified credentials #> function Get-Uptime { [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) { try { 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) { $result = $null $result = Invoke-Command -Session $session -ScriptBlock { [DateTime]::Now - [Management.ManagementDateTimeConverter]::ToDateTime((Get-WmiObject Win32_OperatingSystem).LastBootUpTime) } if ($result) { $props = @{ ComputerName = $computer UpTime = ('{0}:{1}:{2}:{3}:{4}' -f $result.Days, $result.Hours, $result.Minutes, $result.Seconds, $result.Milliseconds) TotalDays = $result.TotalDays TotalHours = $result.TotalHours TotalMinutes = $result.TotalMinutes TotalSeconds = $result.TotalSeconds } New-Object -TypeName System.Management.Automation.PSObject -Property $props | Write-Output } else { '{0} : {1} : Unable to retrieve Win32_Operatingsystem.LastBootupTime informantion!' -f $cmdletName, $computer | Write-Warning } } else { $message = '{0} : {1} : Unable to create PSSession. Ensure PSremoting to {1} is enabled.' -f $cmdletName, $computer if ($Credential -eq $null) { $message += ' Try including the -Credential parameter.' } $message | 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) } } # Kaseya credentials helper function function Save-KCredentials { param ( [parameter(mandatory = $true)] [string]$UserName, [parameter(mandatory = $true)] [securestring]$Password ) try { $filePath = (Join-Path $env:LOCALAPPDATA -ChildPath ('{0}_{1}_kcredentials.xml' -f $env:USERNAME, $env:COMPUTERNAME)) Remove-Item -Path $filePath -Force -ErrorAction SilentlyContinue Get-Credential -Credential ([PScredential]::new($UserName, $Password)) -ErrorAction Stop | Export-Clixml -Path $filePath -Force -ErrorAction Stop Test-Path -Path $filePath | Write-Output } catch { $false | Write-Output } } # Kaseya Connect PowerShell Script generator function Save-KConnect { try { $FilePath = (Join-Path -Path $env:LOCALAPPDATA -ChildPath 'kconnect.ps1') Remove-Item -Path $FilePath -ErrorAction SilentlyContinue $contents = @' $creds = (Import-Clixml -Path (Join-Path -Path $env:LOCALAPPDATA -ChildPath ('{0}_{1}_kcredentials.xml' -f $env:USERNAME, $env:COMPUTERNAME))).GetNetworkCredential() $ie = New-Object -ComObject InternetExplorer.Application $ie.Visible = $true $ie.Navigate2('https://assist.customis.com/vsapres/web20/core/login.aspx') while ($ie.Busy) { Start-Sleep -Seconds 1 } $user = $ie.Document.IHTMLDocument3_getElementById('UsernameTextbox') if ($user) { $user.Value = $creds.UserName } $pass = $ie.Document.IHTMLDocument3_getElementById('PasswordTextbox') if ($pass) { $pass.Value = $creds.Password } $button = $ie.Document.IHTMLDocument3_getElementById('SubmitButton') if ($button) { $button.click() } '@ New-Item -Path $FilePath -Value $contents -Force | Out-Null $true | Write-Output } catch { $false | Write-Output } } function New-KaseyaShortcut { [cmdletbinding()] param ( [string]$FilePath = (Join-Path -Path ([Environment]::GetFolderPath('Desktop')) -ChildPath 'Connect Kaseya.lnk') ) begin { $cmdletName = $PSCmdlet.MyInvocation.MyCommand.Name $timer = New-Object -TypeName System.Diagnostics.StopWatch Write-Verbose -Message ('{0} : {1} : Begin execution' -f $cmdletName, (Get-Date)) $timer.Start() $CredPath = Join-Path -Path $env:LOCALAPPDATA -ChildPath ('{0}_{1}_kcredentials.xml' -f $env:USERNAME, $env:COMPUTERNAME) Write-Verbose -Message ('{0} : Checking for encrypted Kaseya credential file' -f $cmdletName) if (!(Test-Path $CredPath)) { Write-Verbose -Message ('{0} : Could not find encrypted Kaseya credential file. FilePath = {1}' -f $cmdletName, $CredPath) ('Could not find encrypted credential file for {0}\{1}!' -f $env:COMPUTERNAME, $env:USERNAME) | Write-Warning $u = Read-Host -Prompt 'Kaseya user name' $p = Read-Host -Prompt 'Kaseya password' -AsSecureString if (Save-KCredentials -UserName $u -Password $p) { Write-Verbose -Message ('{0} : Successfully saved encrypted Kaseya credential file. FilePath ={0}' -f $cmdletName, $CredPath) ('{0} : Successfully saved encrypted Kaseya credential file.' -f $cmdletName) } else { 'ERROR! Unable to save credential file to {0}' -f $CredPath | Write-Error } } else { Write-Verbose -Message ('{0} : Detected encrypted Kaseya credential file.' -f $cmdletName) } $connPath = Join-Path -Path $env:LOCALAPPDATA -ChildPath 'kconnect.ps1' Write-Verbose -Message ('{0} : Checking for KConnect PowerShell script' -f $cmdletName) if (!(Test-Path $connPath)) { Write-Verbose -Message ('{0} : Could not find Kaseya Connect PowerShell script. ConnPath = {0}' -f $cmdletName, $connPath) if (Save-KConnect) { Write-Verbose -Message ('{0} : Successfully saved Kaseya Connect PowerShell script. ConnPath = {0}' -f $cmdletName, $connPath) ('{0} : Successfully saved Kaseya Connect PowerShell script.' -f $cmdletName) } else { 'ERROR! Unable to save Kaseya Connect PowerShell script to {0}' -f $connPath | Write-Error } } else { Write-Verbose -Message ('{0} : Kaseya Connect PowerShell script already exists.' -f $cmdletName) } } process { try { $shell = New-Object -ComObject Wscript.Shell $shortcut = $shell.CreateShortcut($FilePath) $shortcut.TargetPath = $('C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe') $shortcut.Arguments = (' -noprofile -command "& {0}"' -f (Join-Path -Path $env:LOCALAPPDATA -ChildPath 'kconnect.ps1')) $shortcut.WindowStyle = 7 $shortcut.Save() } catch { throw } } end { $timer.Stop() Write-Verbose -Message ('{0} : {1} : End execution' -f $cmdletName, (Get-Date)) 'Total execution time: {0} ms' -f $timer.ElapsedMilliseconds } } # Portal credentials helper function function Save-PortalCredentials { param ( [parameter(mandatory)] [string]$UserName, [parameter(mandatory)] [securestring]$Password ) try { $filePath = (Join-Path $env:LOCALAPPDATA -ChildPath ('{0}_{1}_portalcredentials.xml' -f $env:USERNAME, $env:COMPUTERNAME)) Remove-Item -Path $filePath -Force -ErrorAction SilentlyContinue Get-Credential -Credential ([PSCredential]::new($UserName, $Password)) -ErrorAction Stop | Export-Clixml -Path $filePath -Force -ErrorAction Stop Test-Path -Path $filePath | Write-Output } catch { $false | Write-Output } } # Portal Connect PowerShell Script generator function Save-PortalConnect { try { $filePath = (Join-Path -Path $env:LOCALAPPDATA -ChildPath 'portalconnect.ps1') Remove-Item -Path $filePath -ErrorAction SilentlyContinue $contents = @' $creds = (Import-Clixml -Path (Join-Path -Path $env:LOCALAPPDATA -ChildPath ('{0}_{1}_portalcredentials.xml' -f $env:USERNAME, $env:COMPUTERNAME))).GetNetworkCredential() $ie = New-Object -ComObject InternetExplorer.Application $ie.Visible = $true $ie.Navigate2('https://portal.customis.com') while ($ie.Busy){Start-Sleep -Seconds 1} try { ($ie.Document.IHTMLDocument3_getElementById('os_username')).Value = $creds.UserName ($ie.Document.IHTMLDocument3_getElementById('os_password')).Value = $creds.Password ($ie.Document.IHTMLDocument3_getElementById('SubmitButton')).click() } catch { throw } '@ New-Item -Path $filePath -Value $contents -Force | Out-Null } catch { $false | Write-Output } } function New-PortalShortcut { [cmdletbinding()] param ( [string]$FilePath = (Join-Path -Path ([Environment]::GetFolderPath('Desktop')) -ChildPath 'Connect Portal.lnk') ) begin { $cmdletName = $PSCmdlet.MyInvocation.MyCommand.Name $timer = New-Object -TypeName System.Diagnostics.StopWatch Write-Verbose -Message ('{0} : {1} : Begin execution' -f $cmdletName, (Get-Date)) $timer.Start() $CredPath = Join-Path -Path $env:LOCALAPPDATA -ChildPath ('{0}_{1}_portalcredentials.xml' -f $env:USERNAME, $env:COMPUTERNAME) Write-Verbose -Message ('{0} : Checking for encrypted Portal credential file' -f $cmdletName) if (!(Test-Path $CredPath)) { Write-Verbose -Message ('{0} : Could not find encrypted Portal credential file. FilePath = {1}' -f $cmdletName, $CredPath) ('Could not find encrypted credential file for {0}\{1}!' -f $env:COMPUTERNAME, $env:USERNAME) | Write-Warning $u = Read-Host -Prompt 'Portal user name' $p = Read-Host -Prompt 'Portal password' -AsSecureString if (Save-KCredentials -UserName $u -Password $p) { Write-Verbose -Message ('{0} : Successfully saved encrypted Portal credential file. FilePath ={0}' -f $cmdletName, $CredPath) ('{0} : Successfully saved encrypted Portal credential file.' -f $cmdletName) } else { 'ERROR! Unable to save credential file to {0}' -f $CredPath | Write-Error } } else { Write-Verbose -Message ('{0} : Detected encrypted Portal credential file.' -f $cmdletName) } $connPath = Join-Path -Path $env:LOCALAPPDATA -ChildPath 'portalconnect.ps1' Write-Verbose -Message ('{0} : Checking for PortalConnect PowerShell script' -f $cmdletName) if (!(Test-Path $connPath)) { Write-Verbose -Message ('{0} : Could not find Portal Connect PowerShell script. ConnPath = {0}' -f $cmdletName, $connPath) if (Save-KConnect) { Write-Verbose -Message ('{0} : Successfully saved Portal Connect PowerShell script. ConnPath = {0}' -f $cmdletName, $connPath) ('{0} : Successfully saved Portal Connect PowerShell script.' -f $cmdletName) } else { 'ERROR! Unable to save Portal Connect PowerShell script to {0}' -f $connPath | Write-Error } } else { Write-Verbose -Message ('{0} : Portal Connect PowerShell script already exists.' -f $cmdletName) } } process { try { $shell = New-Object -ComObject Wscript.Shell $shortcut = $shell.CreateShortcut($FilePath) $shortcut.TargetPath = $('C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe') $shortcut.Arguments = (' -noprofile -command "& {0}"' -f (Join-Path -Path $env:LOCALAPPDATA -ChildPath 'portalconnect.ps1')) $shortcut.WindowStyle = 7 $shortcut.Save() } catch { throw } } end { $timer.Stop() Write-Verbose -Message ('{0} : {1} : End execution' -f $cmdletName, (Get-Date)) 'Total execution time: {0} ms' -f $timer.ElapsedMilliseconds } } |