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 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') $sw = ' [DllImport("user32.dll")] public static extern int ShowWindow(int hwnd, int nCmdShow); ' $type = Add-Type -Name ShowWindow2 -MemberDefinition $sw -Language CSharpVersion3 -Namespace Utils -PassThru $type::ShowWindow($ie.hwnd, 3) 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 } } <# .SYNOPSIS Create a new Kaseya enhanced desktop shortcut .DESCRIPTION Create a new desktop shortcut that launches Internet Explorer, navigates to CIS's Kaseya VSA, programmatically inputs the login credentials, logs in, and maximizes the Internet Explorer window .EXAMPLE New-KaseyaShortcut (First Time) IF THIS IS THE FIRST TIME EVER this script is running, you will be prompted to enter in your Kaseya username and password. This information is securely encrypted and saved in your LocalAppData directory. A PowerShell script to control the interactions with Internet Explorer will also be saved to this directory. A desktop shortcut called "Connect Kaseya" will be created on your desktop. This desktop shortcut file may be moved to any other file system location. NOTE! Moving credential.xml and KConnect.ps1 files will result in this function asking for your credentials and saving these 2 files in the LocalAppData directory again. .EXAMPLE New-KaseyaShortcut (Subsequent Times) If this is NOT the first time ever this function is running, a new Kaseya shortcut will be saved to your desktop. You may move this file after the function has completed. .EXAMPLE New-KaseyaShortcut -Force (Any time) When you supply the -Force parameter, this function will go through it's execution as though as it were the first time it has ever executed. This is useful if you wish to change your current Kaseya credentials. #> function New-KaseyaShortcut { [cmdletbinding()] param ( [string]$FilePath = (Join-Path -Path ([Environment]::GetFolderPath('Desktop')) -ChildPath 'Connect Kaseya.lnk'), [switch]$Force ) 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) $connPath = Join-Path -Path $env:LOCALAPPDATA -ChildPath 'kconnect.ps1' if (!$Force) { Write-Verbose -Message ('{0} : Force not detected' -f $cmdletName) 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) } 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) } } else { Write-Verbose -Message ('{0} : Force detected. Generating new credentials file and Kaseya Connect PowerShell script' -f $cmdletName) Remove-Item -Path $CredPath -Force -ErrorAction SilentlyContinue Remove-Item -Path $connPath -Force -ErrorAction SilentlyContinue Remove-Item -Path $FilePath -Force -ErrorAction SilentlyContinue $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 } 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 } } } 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') $sw = ' [DllImport("user32.dll")] public static extern int ShowWindow(int hwnd, int nCmdShow); ' $type = Add-Type -Name ShowWindow2 -MemberDefinition $sw -Language CSharpVersion3 -Namespace Utils -PassThru $type::ShowWindow($ie.hwnd, 3) while ($ie.Busy){Start-Sleep -Seconds 1} try { $username = $ie.Document.IHTMLDocument3_getElementById('os_username') if ($username) { $username.Value = $creds.UserName } $password = $ie.Document.IHTMLDocument3_getElementById('os_password') if ($password) { $password.Value = $creds.Password } $button = $ie.Document.IHTMLDocument3_getElementById('loginbutton') if ($button) { $button.click() } } catch { throw } '@ New-Item -Path $filePath -Value $contents -Force | Out-Null Test-Path -Path $filePath | Write-Output } catch { $false | Write-Output } } <# .SYNOPSIS Create a new Portal enhanced desktop shortcut .DESCRIPTION Create a new desktop shortcut that launches Internet Explorer, navigates to CIS's Portal, programmatically inputs the login credentials, logs in, and maximizes the Internet Explorer window .EXAMPLE New-PortalShortcut (First Time) IF THIS IS THE FIRST TIME EVER this script is running, you will be prompted to enter in your Portal username and password. This information is securely encrypted and saved in your LocalAppData directory. A PowerShell script to control the interactions with Internet Explorer will also be saved to this directory. A desktop shortcut called "Connect Portal" will be created on your desktop. This desktop shortcut file may be moved to any other file system location. NOTE! Moving credential.xml and PortalConnect.ps1 files will result in this function asking for your credentials and saving these 2 files in the LocalAppData directory again. .EXAMPLE New-PortalShortcut (Subsequent Times) If this is NOT the first time ever this function is running, a new Portal shortcut will be saved to your desktop. You may move this file after the function has completed. .EXAMPLE New-PortalShortcut -Force (Any time) When you supply the -Force parameter, this function will go through it's execution as though as it were the first time it has ever executed. This is useful if you wish to change your current Portal credentials. #> function New-PortalShortcut { [cmdletbinding()] param ( [string]$FilePath = (Join-Path -Path ([Environment]::GetFolderPath('Desktop')) -ChildPath 'Connect Portal.lnk'), [switch]$Force ) 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) $connPath = Join-Path -Path $env:LOCALAPPDATA -ChildPath 'portalconnect.ps1' if (!$Force) { Write-Verbose -Message ('{0} : Force not detected' -f $cmdletName) 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) } 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) } } else { Write-Verbose -Message ('{0} : Force detected. Generating new credentials file and Portal Connect PowerShell script' -f $cmdletName) Remove-Item -Path $CredPath -Force -ErrorAction SilentlyContinue Remove-Item -Path $connPath -Force -ErrorAction SilentlyContinue Remove-Item -Path $FilePath -Force -ErrorAction SilentlyContinue $u = Read-Host -Prompt 'Portal user name' $p = Read-Host -Prompt 'Portal password' -AsSecureString if (Save-PortalCredentials -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 } if (Save-PortalConnect) { 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 } } } 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 } } function Open-Kaseya { [cmdletbinding()] param ( [parameter()] [string]$VsaUrl = 'https://assist.customis.com/vsapres/web20/core/login.aspx', [parameter()] [string]$CredPath = (Join-Path $env:LOCALAPPDATA -ChildPath ('{0}_{1}_portalcredentials.xml' -f $env:USERNAME, $env:COMPUTERNAME)) ) begin { $timer = [System.Diagnostics.Stopwatch]::new() $cmdletName = $PSCmdlet.MyInvocation.MyCommand.Name Write-Verbose -Message ('{0} : Begin execution : {1}' -f $cmdletName, (Get-Date)) $timer.Start() } process { try { Write-Verbose -Message ('{0} : Creating IE ComObject...' -f $cmdletName) $ie = New-Object -ComObject InternetExplorer.Application $ie.Visible = $true Write-Verbose -Message ('{0} : Navigating to {1}' -f $cmdletName, $VsaUrl) $ie.Navigate2($VsaUrl) Write-Verbose -Message ('{0} : Setting IE window to maximum...' -f $cmdletName) $sw = '[DllImport("user32.dll")]' + [environment]::NewLine + 'public static extern int ShowWindow(int hwnd, int nCmdShow);' $type = Add-Type -Name ShowWindow2 -MemberDefinition $sw -Language CSharpVersion3 -Namespace utils -PassThru $type::ShowWindow($ie.hwnd, 3) | Out-Null while ($ie.Busy) { Write-Verbose -Message ('{0} : IE busy... waiting 1 second...' -f $cmdletName) Start-Sleep -Seconds 1 } Write-Verbose -Message ('{0} : Checking for {1}' -f $cmdletName, $CredPath) if (Test-Path -Path $CredPath) { Write-Verbose -Message ('{0} : Detected credentials' -f $cmdletName) $creds = (Import-Clixml -Path $CredPath).GetNetworkCredential() $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) { Write-Verbose -Message ('{0} : Logging in...' -f $cmdletName) $button.click() } } else { Write-Warning -Message ('{0} : Could not find {1}. We were unable to parse Kaseya credentials...') } } 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 Enable RDP connections .DESCRIPTION Configures the registry to allow secure RDP connections and enables the Remote Administration and Remote Desktop firewall rule group .EXAMPLE Enable-Rdp This example will configure the registry to allow secure RDP connections and enables the Remote Administration and Remote Desktop firewall rule group on the local computer .EXAMPLE Enable-Rdp -ComputerName Computer1, Computer2 -Credential (Get-Credential) This example will configure the registry to allow secure RDP connections and enables the Remote Administration and Remote Desktop firewall rule group on the remote computers, Computer1 and Computer2, using the supplied credentials .EXAMPLE Get-Content C:\file.txt | Enable-Rdp -Credential (Get-Credential) This example will configure the registry to allow secure RDP connections and enables the Remote Administration and Remote Desktop firewall rule group on the computer names found in the file c:\file.txt, using the supplied credentials #> function Enable-RDP { [cmdletbinding()] param ( [parameter(ValueFromPipeline, ValueFromPipelineByPropertyName)] [string[]]$ComputerName = $env:COMPUTERNAME, [parameter()] [pscredential]$Credential ) begin { $timer = [System.Diagnostics.Stopwatch]::new() $cmdletName = $PSCmdlet.MyInvocation.MyCommand.Name Write-Verbose -Message ('{0} : Begin execution : {1}' -f $cmdletName, (Get-Date)) $timer.Start() } process { foreach ($computer in $ComputerName) { $cTimer = [System.Diagnostics.Stopwatch]::new() $cTimer.Start() try { Write-Verbose -Message ('{0} : {1} : Begin execution' -f $cmdletName, $computer) $sessionParams = @{ComputerName = $computer ErrorAction = 'SilentlyContinue'} if ($Credential -ne $null) { Write-Verbose -Message ('{0} : {1} : Using supplied credentials' -f $cmdletName, $computer) $sessionParams.Add('Credential', $Credential) } else { Write-Verbose -Message ('{0} : {1} : Using default credentials' -f $cmdletName, $computer) } $session = New-PSSession @sessionParams if ($session) { Write-Verbose -Message ('{0} : {1} : Successfully created PSSession' -f $cmdletName, $computer) $result = Invoke-Command -Session $session -ScriptBlock { try { Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -Name fDenyTSConnections -Value 0 -Force Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -Name UserAuthentication -Value 0 -Force Enable-NetFirewallRule -DisplayGroup 'Remote Desktop' | Out-Null $true | Write-Output } catch { throw } } Write-Verbose -Message ('{0} : {1} : Execution complete' -f $cmdletName, $computer) Remove-PSSession -Session $session $cTimer.Stop if ($result -eq $true) { New-Object -TypeName System.Management.Automation.PSObject -Property @{ComputerName = $computer Operation = 'Enable RDP' Result = $result ExecTimeMS = $cTimer.ElapsedMilliseconds} } else { Write-Warning -Message ('{0} : {1} : Something unexpected happened... here is what we know...' -f $cmdletName, $computer) $result } } else { Write-Warning -Message ('{0} : {1} : Could not create PS session!' -f $cmdletName, $computer) if ($Credential -eq $null) { Write-Warning -Message ('{0} : {1} : Try including the -Credential parameter' -f $cmdletName, $computer) } } } catch { throw } finally { } } } end { $timer.Stop() Write-Verbose -Message ('{0} : End execution' -f $cmdletName) Write-Verbose -Message ('{0} : Total execution time : {1} ms' -f $cmdletName, $timer.ElapsedMilliseconds) } } <# .SYNOPSIS Connect to CIS Replibit resources .DESCRIPTION This function connects you to CIS Replibit BDR's, Vaults, or the Licensing Portal. .EXAMPLE Connect-Bdr -BdrName CISBDR This example will connect you to CISBDR's web management GUI. .EXAMPLE Connect-Bdr -BdrName CISBDR, CISHOSTBDR -SSH This example will connect you to the SSH port on CISBDR and CISHOSTBDR .EXAMPLE Connect-Bdr -LicensePortal This example will connect you to CIS's Replibit Licensing Portal #> function Connect-BDR { [cmdletBinding()] param ( [validateSet('FILBDR','Vault1','RASBDR','CISBDR','BROBDR','NEUBDR','TYSBDR','CISHOSTBDR', 'OVEBDR','CWMBDR','DOLFTWBDR','QUABDR','QUAPRODBDR','Vault3','MASBDR', 'Vault4','EMGBDR','CRWBDR01','Vault2','WINBDR01','OVEBDR01','Vault5')] [parameter(ValueFromPipeline, ValueFromPipelineByPropertyName, ParameterSetName = 'target')] [string[]]$BDRName, [parameter(ParameterSetName = 'all')] [switch]$AllBDRs, [parameter(ParameterSetName = 'vault')] [switch]$AllVaults, [parameter(ParameterSetName = 'License')] [switch]$LicensePortal, [parameter(ParameterSetName = 'License')] [string]$LicensePortalUri = 'https://licensing.replibit.com/index.html', [parameter(ParameterSetName = 'target')] [parameter(ParameterSetName = 'all')] [switch]$SSH, [parameter(ParameterSetName = 'target')] [parameter(ParameterSetName = 'all')] [parameter(ParameterSetName = 'vault')] [string]$BaseUri = 'https://rb-customis-mgmt.rb.slc.efscloud.net:' ) begin { $timer = [System.Diagnostics.Stopwatch]::new() $cmdletName = $PSCmdlet.MyInvocation.MyCommand.Name Write-Verbose -Message ('{0} : Begin execution : {1}' -f $cmdletName, (Get-Date)) $bdrPorts = @{ FILBDR = '10000' Vault1 = '10001' Vault5 = '10002' RASBDR = '10003' CISBDR = '10004' BROBDR = '10005' NEUBDR = '10006' TYSBDR = '10007' CISHOSTBDR = '10008' OVEBDR = '10009' CWMBDR = '10010' DOLFTWBDR = '10011' QUABDR = '10013' QUAPRODBDR = '10014' Vault3 = '10015' MASBDR = '10016' Vault4 = '10017' EMGBDR = '10018' CRWBDR01 = '10020' Vault2 = '10021' WINBDR01 = '10023' OVEBDR01 = '10024' } $timer.Start() } process { Write-Verbose -Message ('{0} : Parameter set name : {1}' -f $cmdletName, $PSCmdlet.ParameterSetName) if ($PSCmdlet.ParameterSetName -ne 'license') { switch ($PSCmdlet.ParameterSetName) { 'target' { $bdrs = $BDRName } 'all' { $bdrs = (Get-Variable -Name 'bdrPorts').value.keys | Where-Object {$_ -notlike '*vault*'} | Sort-Object } 'vault' { $bdrs = (Get-Variable -Name 'bdrPorts').value.keys | Where-Object {$_ -like '*vault*'} | Sort-Object } } foreach ($bdr in $bdrs) { Write-Verbose -Message ('{0} : {1} : Begin execution' -f $cmdletName, $bdr) try { $uri = $BaseUri + $bdrPorts.$bdr Write-Verbose -Message ('{0} : {1} : SSH? {2}' -f $cmdletName, $bdr, $SSH.IsPresent) if ($SSH) { $uri = $uri + '/ssh' } Write-Verbose -Message ('{0} : {1} : Uri : {2}' -f $cmdletName, $bdr, $uri) [System.Diagnostics.Process]::Start($uri) New-Object -TypeName System.Management.Automation.PSObject -Property @{BDR = $bdr Port = $bdrPorts.$bdr Uri = $uri SSH = $SSH Result = $true} | Write-Output } catch { throw } Write-Verbose -Message ('{0} : {1} : End execution' -f $cmdletName, $bdr) } } else { Write-Verbose -Message ('{0} : Connecting to Replibit Licensing portal' -f $cmdletName) [System.Diagnostics.Process]::Start($LicensePortalUri) New-Object -TypeName System.Management.Automation.PSObject -Property @{BDR = 'Licensing Portal' Port = $null Uri = $LicensePortalUri SSH = $null Result = $true} | Write-Output } } end { $timer.Stop() Write-Verbose -Message ('{0} : End execution' -f $cmdletName) Write-Verbose -Message ('{0} : Total execution time : {1} ms' -f $cmdletName, $timer.ElapsedMilliseconds) } } <# .SYNOPSIS .DESCRIPTION .PARAMETER .PARAMETER .EXAMPLE .EXAMPLE .EXAMPLE #> function Get-DotNetVersion { [CmdletBinding()] param ( [parameter(ValueFromPipeline, ValueFromPipelineByPropertyName)] [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 = 'SilentlyContinue'} if ($Credential -ne $null) { Write-Verbose -Message ('{0} : {1} : Using supplied credentials' -f $cmdletName, $computer) $sessionParams.Add('Credential', $Credential) } else { Write-Verbose -Message ('{0} : {1} : Using default credentials' -f $cmdletName, $computer) } Invoke-Command @sessionParams -ScriptBlock { Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse | Get-ItemProperty -Name Version, Release -EA SilentlyContinue | Where-Object {$_.PSChildName -match '^(?![SW])\p{L}'} | Select-Object -Property @{ Name = "Product" Expression = {$_.PSChildName} }, Version } | Select PSComputerName, Version, Product } } end { $timer.Stop() Write-Verbose -Message ('{0} : End execution' -f $cmdletName) Write-Verbose -Message ('Total execution time: {0} ms' -f $timer.Elapsed.TotalMilliseconds) } } |