NewDDLSImageInstructorTools.psm1
function Get-DDLSSubnetIPInfo { <# .SYNOPSIS This command finds all of the IP addresses that are possible in the current subnet .DESCRIPTION This command takes the IP address and subnet masl from the current computer and then works out the subnet length to produce, as an output a custom object with the following properties: HostIPAddress HostSubnetMask FirstSubnetIP LastSubnetIP AllValidIPs AllValidStudentIPs .EXAMPLE Get-DDLSSubnetIPInfo There is no parameters to supply to this command as is gathers all that it needs from the Instructor PC .NOTES General notes Created by: Brent Denny Created on: 13 Dec 2019 #> [CmdletBinding()] Param() try { $PhysicalAdatpter = Get-NetAdapter -Physical -ErrorAction Stop | Where-Object {$_.Status -eq 'up'} $MyPcIpaddressObj = Get-NetIPAddress -AddressFamily IPv4 -InterfaceIndex $PhysicalAdatpter.ifIndex -ErrorAction Stop if (-not $MyPcIpaddressObj) {throw 'Error finding adapter or IPaddress'} } Catch { try { $HyperVAdatpter = Get-NetAdapter | Where-Object {$_.ifIndex -ne $PhysicalAdatpter.ifIndex} -ErrorAction Stop | Where-Object {$_.Status -eq 'up'} $MyPcIpaddressObj = Get-NetIPAddress -AddressFamily IPv4 -InterfaceIndex $HyperVAdatpter.ifIndex -ErrorAction Stop if (-not $MyPcIpaddressObj) {throw 'Error finding adapter or IPaddress'} } catch {Write-Warning 'No Adapter could be found for this computer'} } [string[]]$AllIPinSubnet = @() $SubnetJumpValue = [math]::Pow(2,(8 - ($MyPcIpaddressObj.PrefixLength % 8))) #What is the current jump value for each new subnet $RevMYIPOctets = ($MyPcIpaddressObj.IPAddress -split '\.')[3..0] # Reversing the octets and then creating an [IPAddress] object allows easy math functions in the IP address [ipaddress]$RevIPAddress = $RevMYIPOctets -join '.' [bigint]$RevSubnetMaskValue = 4294967295 - ([math]::Pow(2,32 - $MyPcIpaddressObj.PrefixLength)) +1 [ipaddress]$DottedRevSubnetMask = 4294967295 # Instantiating new IPAddress object $DottedRevSubnetMask.Address = $RevSubnetMaskValue # Assigning real subnetmask value to newly created object $RevSubnetMaskOctets = ($DottedRevSubnetMask.IPAddressToString -split '\.')[3..0] [ipaddress]$ForwardSubnetMaskAddress = $RevSubnetMaskOctets -join '.' [bigint]$AndedResult = $RevSubnetMaskValue -band $RevIPAddress.Address $FirstValidRevIP = [ipaddress]::New($AndedResult + 1) $LastValidRevIP = [ipaddress]::New($FirstValidRevIP.address + $SubnetJumpValue - 3) [bigint[]]$Range = @() [bigint]$StartRange = $AndedResult + 1 [bigint]$EndRange = $AndedResult + $SubnetJumpValue - 2 for ($StartRange;$StartRange -le $EndRange; $StartRange = $StartRange + 1) {$Range += $StartRange} foreach ($RevNum in $Range){ $TempRevIP = ([ipaddress]::new($RevNum)).IPAddressToString [string[]]$AllIPinSubnet += (($TempRevIP -split '\.')[3..0]) -join '.' } [ipaddress]$FirstValidIP = ($FirstValidRevIP.IPAddressToString -split '\.')[3..0] -join '.' [ipaddress]$LastValidIP = ($LastValidRevIP.IPAddressToString -split '\.')[3..0] -join '.' $Hash = [ordered]@{ HostIPAddress = $MyPcIpaddressObj.IPAddress HostSubnetMask = $ForwardSubnetMaskAddress FirstSubnetIP = $FirstValidIP LastSubnetIP = $LastValidIP AllValidIPs = $AllIPinSubnet AllValidStudentIPs = $AllIPinSubnet | Where-Object {$_ -ne $MyPcIpaddressObj.IPAddress} } return New-Object -TypeName psobject -Property $Hash } function New-DDLSStudentPSSessions { <# .SYNOPSIS This command creates PS sessions to DDLS Student PCs .DESCRIPTION This command takes into account the IP address of the machine you are running the script from and treats it as though it was the Instructor PC, what this means is that it automatically excludes its own IP address from the IPs it uses to establish classroom sessions. .PARAMETER AlternateCredentials This parameter is a switch parameter that will trigger the use of alternate credentials to connect to student computers, this is useful if the instructor has changed the password on the instructor PC. .EXAMPLE New-DDLSStudentPSSessions Running this script calls upon another cmdlet that will discover the IPs in the classroom, the output of this called cmdlet shows first and last IP in the subnet, Subnet mask, all valid IPs and all IPs excluding the current IP of the computer where this script is running. Using the following syntax you can store the PSSession information in the variable $StudentSessions which then can be used with the other commands in this module. $StudentSessions = New-DDLSStudentPSSessions .EXAMPLE New-DDLSStudentPSSessions -AlternateCredentials Running this script calls upon another cmdlet that will discover the IPs in the classroom, the output of this called cmdlet shows first and last IP in the subnet, Subnet mask, all valid IPs and all IPs excluding the current IP of the computer where this script is running. Using the following syntax you can store the PSSession information in the variable $StudentSessions which then can be used with the other commands in this module. This will also request that alternate credentials are used for the connections to the student machines, this is especially usefull if the instructor has changed the password on the instructor PC. $StudentSessions = New-DDLSStudentPSSessions -AlternateCredentials .NOTES General notes Created by: Brent Denny Created on: 13 Dec 2019 Modified on: 23 Jan 2020 #> [CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='Medium')] Param( [switch]$AlternateCredentials ) Set-Item -Path WSMan:\localhost\Client\TrustedHosts -Value '*' -Force $StudentIPs = (Get-DDLSSubnetIPInfo).AllValidStudentIPs Get-PSSession | Remove-PSSession | Out-Null Write-Warning "Please wait while sessions are established" $SessOpt = New-PSSessionOption -MaxConnectionRetryCount 0 -MaximumRedirection 0 if ($AlternateCredentials -eq $true) { if ($PSCmdlet.ShouldProcess("Clasroom Student PCs", "Setting up PowerShell sessions")) { $NewCredential = Get-Credential -Message 'Enter name and password' -UserName 'Administrator' New-PSSession -ComputerName $StudentIPs -ErrorAction SilentlyContinue -ThrottleLimit 180 -SessionOption $SessOpt -Credential $NewCredential | Where-Object {$_.State -eq 'Opened' -and $_.Availability -eq 'Available' } } } Else { if ($PSCmdlet.ShouldProcess("Clasroom Student PCs", "Setting up PowerShell sessions")) { New-PSSession -ComputerName $StudentIPs -ErrorAction SilentlyContinue -ThrottleLimit 180 -SessionOption $SessOpt | Where-Object {$_.State -eq 'Opened' -and $_.Availability -eq 'Available' } } } } function Restart-DDLSStudentPC { <# .SYNOPSIS This command will restart all of the computers that this computer can make PS sessions to, in the current subnet. .DESCRIPTION If you supply the sessions as a parameter this command will check if any are stale and remake those sessions, once all of the sessions are available this will proceed to restart each computer after a given inverval, this interval will assist us in selecting f12 when it boots to lay down a new image for the next class .EXAMPLE Restart-DDLSStudentPC -StudentSessions $ClassSessions -SecondsBetweenReboots 25 This will send restart commands each 25 seconds to each of the sessions given to the parameter StudentSessions. To create the $StudentSessions variable run the following command before running this command: $StudentSessions = New-DDLSStudentPSSessions .EXAMPLE Restart-DDLSStudentPC This will first establish PS sessions to the student PCs and then send restart commands each 20 seconds to each of the sessions, 20 Seconds is the default .PARAMETER StudentSessions This accepts PSSession objects that were created to every student PC. If this parameter is omitted the command will create its own sessions, but this can take 20 - 30 seconds to complete. To create the $StudentSessions variable run the following command before running this command: $StudentSessions = New-DDLSStudentPSSessions .PARAMETER SecondsBetweenReboots Enter an integer value for the number of seconds to wait before the next reboot .NOTES General notes Created by: Brent Denny Created on: 13 Dec 2019 #> [CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='Medium')] Param ( $StudentSessions = (New-DDLSStudentPSSessions), $SecondsBetweenReboots = 20 ) if ($PSCmdlet.ShouldProcess("Clasroom Student PCs", "Restarting")) { if ($StudentSessions.State -contains 'Broken') {$StudentSessions = (New-DDLSStudentPSSessions)} $StudentSessions | ForEach-Object { Invoke-Command -Session $_ -ScriptBlock {Restart-Computer -force} Start-Sleep -Seconds $SecondsBetweenReboots } } } function Copy-DDLSFileToStudentPC { <# .SYNOPSIS This command can copy a file to the student PCs in the room .DESCRIPTION This command uses a powershell session to each student computer and then the Copy-Item -ToSession command to copy the file to the computer without the need for RPC access .EXAMPLE Copy-DDLSFileToStudentPC -StudentSessions $ClassSessions -FilePath d:\file.pdf -DestinationPath c:\ This will copy a file from the local PCs D:\ drive, called file.pdf, to each student computer's C:\ drive. .PARAMETER StudentSessions This accepts PSSession objects that were created to every student PC. If this parameter is omitted the command will create its own sessions, but this can take 20 - 30 seconds to complete. To create the $StudentSessions variable run the following command before running this command: $StudentSessions = New-DDLSStudentPSSessions .PARAMETER FilePath Points to the file that will be copied to the Student PCs .PARAMETER Destination Points to the directory on the student PC where the file wil be copied to, if this is omitted then the default detination will be the student's desktop .NOTES General notes Created by: Brent Denny Created on: 13 Dec 2019 #> [CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='Medium')] Param ( $StudentSessions = (New-DDLSStudentPSSessions), [Parameter(Mandatory=$true)] [string]$FilePath, $DestinationPath = 'C:\users\Administrator\Desktop\' ) if ($StudentSessions.State -contains 'Broken') {$StudentSessions = (New-DDLSStudentPSSessions)} $Counter = 0 ForEach ($StudentSession in $StudentSessions) { $Counter++ if ($PSCmdlet.ShouldProcess("IP address $($StudentSession.Comptername)", "Copy file")) { Copy-Item -ToSession $StudentSession -Path $FilePath -Destination $DestinationPath -Force } Write-Host "Copied to $Counter computer/s" } } function Set-DDLSPowerOptions { <# .SYNOPSIS This command disables the sleep settings in the power options of the student PCs .DESCRIPTION This command disables the sleep settings in the power options of the student PCs by using powercfg.exe settings .EXAMPLE Set-DDLSPowerOptions -StudentSessions $ClassSessions This runs the PowerCFG commands on every student PC that it has a PS session to .PARAMETER StudentSessions This accepts PSSession objects that were created to every student PC. If this parameter is omitted the command will create its own sessions, but this can take 20 - 30 seconds to complete. To create the $StudentSessions variable run the following command before running this command: $StudentSessions = New-DDLSStudentPSSessions .NOTES General notes Created by: Brent Denny Created on: 13 Dec 2019 #> [CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='Medium')] Param ( $StudentSessions = (New-DDLSStudentPSSessions) ) if ($PSCmdlet.ShouldProcess("Clasroom Student PCs", "Disabling Sleep settings")) { if ($StudentSessions.State -contains 'Broken') {$StudentSessions = (New-DDLSStudentPSSessions)} Invoke-Command -Session $StudentSessions -ScriptBlock { & powercfg.exe /x -hibernate-timeout-ac 0 & powercfg.exe /x -disk-timeout-ac 0 & powercfg.exe /x -monitor-timeout-ac 0 & Powercfg.exe /x -standby-timeout-ac 0 } } } function Disable-DDLSLanguageHotKey { <# .SYNOPSIS This command disables the language switching hotkey on the student PCs .DESCRIPTION This command disables the language switching hotkey on the student PCs by using Registry hacks .EXAMPLE Disable-DDLSLanguageHotKey -StudentSessions $ClassSessions This edits the registry on every student PC that it has a PS session to .PARAMETER StudentSessions This accepts PSSession objects that were created to every student PC. If this parameter is omitted the command will create its own sessions, but this can take 20 - 30 seconds to complete. To create the $StudentSessions variable run the following command before running this command: $StudentSessions = New-DDLSStudentPSSessions .NOTES General notes Created by: Brent Denny Created on: 13 Dec 2019 #> [CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='Medium')] Param ( $StudentSessions = (New-DDLSStudentPSSessions) ) if ($PSCmdlet.ShouldProcess("Clasroom Student PCs", "Disabling KB layout hotkey")) { if ($StudentSessions.State -contains 'Broken') {$StudentSessions = (New-DDLSStudentPSSessions)} Invoke-Command -Session $StudentSessions -ScriptBlock { Set-ItemProperty -Path 'HKCU:\Keyboard Layout\Toggle' -Name 'Language Hotkey' -Value 3 Set-ItemProperty -Path 'HKCU:\Keyboard Layout\Toggle' -Name 'Hotkey' -Value 3 Set-ItemProperty -Path 'HKCU:\Keyboard Layout\Toggle' -Name 'Layout Hotkey' -Value 3 } } } function Enable-DDLSAutoLogon { <# .SYNOPSIS This command is meant to enable AutoAdminLogon on the student PCs, It does not work yet .DESCRIPTION This command is meant to enable AutoAdminLogon on the student PCs, It does not work yet .EXAMPLE Enable-DDLSAutoLogon -StudentSessions $ClassSessions This edits the registry on every student PC that it has a PS session to .PARAMETER StudentSessions This accepts PSSession objects that were created to every student PC. If this parameter is omitted the command will create its own sessions, but this can take 20 - 30 seconds to complete. To create the $StudentSessions variable run the following command before running this command: $StudentSessions = New-DDLSStudentPSSessions .NOTES General notes Created by: Brent Denny Created on: 13 Dec 2019 #> [CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='Medium')] Param ( $StudentSessions = (New-DDLSStudentPSSessions) ) if ($PSCmdlet.ShouldProcess("Clasroom Student PCs", "Setting up Autologon")) { if ($StudentSessions.State -contains 'Broken') {$StudentSessions = (New-DDLSStudentPSSessions)} Invoke-Command -Session $StudentSessions -ScriptBlock { Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' -Name 'DefaultDomainName' -Value 'Administrator' Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' -Name 'DefaultPassword' -Value 'password' Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' -Name 'DefaultUserName' -Value 'Administrator' Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' -Name 'AutoAdminLogon' -Value 1 } } } |