SCONFIG.ps1
# Script Name: SCONFIG.ps1 # Current Version: 1.8 # Written By: Peter Remstad # Date Created: 2018-03-28 # Date Revised: 2020-01-02 # # Notes: v1.0 - Feature complete when comparing to old sconfig.vbs that ships with Windows # Server. # v1.1 - Improvement: Updated input text for options 1-7 to be more consistent # v1.2 - Set ideal buffer size for script. Prevents awkward text wrapping. # v1.3 - Re-ordered main menu options to a more logical order. Add in two options # which will be developed soon. # v1.4 - Firewall toggling added. # v1.5 - Windows Defender toggling added. # v1.6 - NIC Teaming configurations added, updated network config to handle teaming. # v1.7 - Bug fixes # v1.8 - Added requirement for Computer renaming, name may not consist of only # digits. Update sc_Set-Domain function to be consistent with new Computer # naming error and change where an error returns the prompt. # ############################################################################################ <#PSScriptInfo .VERSION 1.8 .GUID 465df723-0dac-4bed-95f6-8a403596fe74 .AUTHOR Peter Remstad .COMPANYNAME .COPYRIGHT .TAGS SCONFIG Configuration Server .LICENSEURI .PROJECTURI .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES #> <# .DESCRIPTION Provides SCONFIG functionality through Powershell, cleans up user interface, adds additional functionality from built-in Microsoft SCONFIG.vbs. Script operates correctly on Windows Server 2016 and newer server operating systems. #> Param() ###################################################### EXECUTE SYSTEM INFO QUERY ####################################################### function sc_Create-MainMenu ( ) { # RESETS ALL VARIABLES FOR FUNCTION $ErrorActionPreference = "SilentlyContinue" $Domain = $null $CompSys = $null $Remote = $null $AU = $null $Update = $null $TSConnect = $null $UserAuth = $null $RDP = $null $TelReg = $null $Telem = $null $TimeZone = $null $ConProf = $null $FWStatus = $null $Firewall = $null Write-Host -ForegroundColor Cyan "Gathing information..." # GATHERS ALL DATA $CompSys = Get-WmiObject -Class Win32_ComputerSystem $Remote = Configure-SMRemoting.exe -Get $AU = Get-ItemProperty -Path "HKLM:\\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" $NoAU = $AU.NoAutoUpdate $AU = $AU.AUOptions $TSConnect = (Get-ItemProperty -Path "HKLM:\\SYSTEM\CurrentControlSet\Control\Terminal Server").fDenyTSConnections $UserAuth = (Get-ItemProperty -Path "HKLM:\\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-TCP").UserAuthentication $TelReg = (Get-ItemProperty -Path "HKLM:\\SOFTWARE\Policies\Microsoft\Windows\DataCollection").AllowTelemetry $TimeZone = Get-TimeZone | Select -Property DisplayName # GETS LOCAL TELEMETRY SETTING IF GROUP POLICY SETTING DOESN'T EXIST/APPLY If ($TelReg -eq $null) { $TelReg = (Get-ItemProperty -Path "HKLM:\\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\DataCollection").AllowTelemetry } # MANIPULATES DATA FOR DOMAIN If (($CompSys.DomainRole -eq 0) -or ($CompSys.DomainRole -eq 2)) { $Domain = "Workgroup: $($CompSys.Domain)" } ElseIf (($CompSys.DomainRole -eq 1) -or ($CompSys.DomainRole -eq 3) -or ($CompSys.DomainRole -eq 4) -or ($CompSys.DomainRole -eq 5)) { $Domain = "Domain: $($CompSys.Domain)" } # PROVIDES OUTPUT IF QUERY FAILED FOR REMOTE MANAGEMENT SETTINGS If ($Remote -eq $null) { $Remote = "Failed query" } ElseIf ($Remote -match "disabled") { $Remote = "Disabled" } ElseIf ($Remote -match "enabled") { $Remote = "Enabled" } # TRANSLATES REGISTRY FOR WINDOWS UPDATE TO USER FRIENDLY OUTPUT Switch ($AU) { $null {If ($NoAU -eq 1) {$Update = "Manual"} ElseIf ($NoAU -eq $null) {$Update = "Failed Query"} ; break} 1 {$Update = "Never check for updates" ; break} 2 {$Update = "Notify before download" ; break} 3 {$Update = "DownloadOnly" ; break} 4 {$Update = "Automatic" ; break} } # TRANSLATES REGISTRY FOR RDP CONFIG TO USER FRIENDLY OUTPUT Switch ($TSConnect) { $null {$RDP = "Failed Query" ; break} 0 {If ($UserAuth -eq 0) {$RDP = "Enabled (all clients)"} ElseIf ($UserAuth -eq 1) {$RDP = "Enabled (more secure clients only)"} Else {$RDP = "Failed Query"} ; break} 1 {$RDP = "Disabled" ; break} } # TRANSLATES TELEMETRY SETTINGS TO USER FRIENDLY OUTPUT Switch ($TelReg) { $null {$Telem = "Failed Query" ; break} 0 {$Telem = "Security" ; break} 1 {$Telem = "Basic" ; break} 2 {$Telem = "Enhanced" ; break} 3 {$Telem = "Full" ; break} } # GATHERS CONNECTED NETWORK PROFILES $ConProf = Get-NetConnectionProfile $ConProf = $ConProf.NetworkCategory | Select -Unique # GATHERS THE FIREWALL STATUS OF ALL CONNECTED FIREWALL PROFILES If ($ConProf.count -eq 1) { # MODIFIES CONNECTED PROFILE TO USABLE VALUE If ($ConProf -eq "DomainAuthenticated") { $ConProf = "Domain" } # GATHERS ASSOCIATED FIREWALL PROFILE $FWStatus = (Get-NetFirewallProfile -Name $ConProf).Enabled # TRANSLATES STATUS Switch ($FWStatus) { $true {$FWStatus = "Enabled" ; break} $false {$FWStatus = "Disabled" ; break} } # GENERATES STRING $Firewall = "$ConProf`: $FWStatus" } Else { Foreach ($Prof in $ConProf) { # MODIFIES CONNECTED PROFILE TO USABLE VALUE If ($Prof -eq "DomainAuthenticated") { $Prof = "Domain" } # GATHERS ASSOCIATED FIREWALL PROFILE $FWStatus = (Get-NetFirewallProfile -Name $ConProf).Enabled Switch ($FWStatus) { $true {$FWStatus = "Enabled" ; break} $false {$FWStatus = "Disabled" ; break} } # GENERATES STRING $Firewall += "$Prof`: $FWStatus " } } $TextArray = @() $TextArray += New-Object -TypeName psobject -Property @{Item = "1) Domain/Workgroup:"} $TextArray += New-Object -TypeName psobject -Property @{Item = "$Domain"} $TextArray += New-Object -TypeName psobject -Property @{Item = "2) Computer Name:"} $TextArray += New-Object -TypeName psobject -Property @{Item = "$($CompSys.PSComputerName)"} $TextArray += New-Object -TypeName psobject -Property @{Item = "3) Add Local Administrator"} $TextArray += New-Object -TypeName psobject -Property @{Item = ""} $TextArray += New-Object -TypeName psobject -Property @{Item = "4) Date and Time:"} $TextArray += New-Object -TypeName psobject -Property @{Item = "$($TimeZone.DisplayName)"} $TextArray += New-Object -TypeName psobject -Property @{Item = ""} $TextArray += New-Object -TypeName psobject -Property @{Item = ""} $TextArray += New-Object -TypeName psobject -Property @{Item = "5) Network Settings"} $TextArray += New-Object -TypeName psobject -Property @{Item = ""} $TextArray += New-Object -TypeName psobject -Property @{Item = "6) NIC Teaming"} $TextArray += New-Object -TypeName psobject -Property @{Item = ""} $TextArray += New-Object -TypeName psobject -Property @{Item = "7) Firewall Settings:"} $TextArray += New-Object -TypeName psobject -Property @{Item = "$Firewall"} $TextArray += New-Object -TypeName psobject -Property @{Item = "8) Telemetry Settings:"} $TextArray += New-Object -TypeName psobject -Property @{Item = "$Telem"} $TextArray += New-Object -TypeName psobject -Property @{Item = "9) Windows Activation"} $TextArray += New-Object -TypeName psobject -Property @{Item = ""} $TextArray += New-Object -TypeName psobject -Property @{Item = ""} $TextArray += New-Object -TypeName psobject -Property @{Item = ""} $TextArray += New-Object -TypeName psobject -Property @{Item = "10) Windows Defender"} $TextArray += New-Object -TypeName psobject -Property @{Item = ""} $TextArray += New-Object -TypeName psobject -Property @{Item = "11) Configure Remote Management:"} $TextArray += New-Object -TypeName psobject -Property @{Item = "$Remote"} $TextArray += New-Object -TypeName psobject -Property @{Item = "12) Remote Desktop:"} $TextArray += New-Object -TypeName psobject -Property @{Item = "$RDP"} $TextArray += New-Object -TypeName psobject -Property @{Item = "13) Windows Update Settings:"} $TextArray += New-Object -TypeName psobject -Property @{Item = "$Update"} $TextArray += New-Object -TypeName psobject -Property @{Item = "14) Download and Install Updates"} $TextArray += New-Object -TypeName psobject -Property @{Item = ""} $TextArray += New-Object -TypeName psobject -Property @{Item = ""} $TextArray += New-Object -TypeName psobject -Property @{Item = ""} $TextArray += New-Object -TypeName psobject -Property @{Item = "15) Log Off User"} $TextArray += New-Object -TypeName psobject -Property @{Item = ""} $TextArray += New-Object -TypeName psobject -Property @{Item = "16) Restart Server"} $TextArray += New-Object -TypeName psobject -Property @{Item = ""} $TextArray += New-Object -TypeName psobject -Property @{Item = "17) Shut Down Server"} $TextArray += New-Object -TypeName psobject -Property @{Item = ""} $TextArray += New-Object -TypeName psobject -Property @{Item = "18) Exit to Command Line"} $TextArray += New-Object -TypeName psobject -Property @{Item = ""} # GENERATES OUTPUT TEXT $OutputText = " ==================================================================================== Server Configuration ====================================================================================" # RETURNS TEXT DATA Write-Output $OutputText $TextArray | Format-Wide -Property Item -Column 2 # DEFINES VALID OPTIONS $ValidInput = @(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18) # GATHERS SELECTED OPTION [int]$Choice = Read-Host "Enter number to select an option" # VALIDATES SELECTED OPTION ; RETURNS TO MAIN MENU ON BAD INPUT If ($ValidInput -notcontains $Choice) { Write-Host -ForegroundColor Yellow "Invalid input, returning to main menu..." Start-Sleep -Seconds 1 sc_Create-MainMenu } # EXECUTES SELECTED OPTION Switch ($Choice) { 1 {sc_Set-Domain ; break} 2 {sc_Set-ComputerName ; break} 3 {sc_Add-LocalAdmin ; break} 4 {sc_Set-DateTime ; break} 5 {sc_Set-Network ; break} 6 {sc_Config-NICTeaming ; break} 7 {sc_Set-Firewall ; break} 8 {sc_Set-Telemetry ; break} 9 {sc_Set-WinAct ; break} 10 {sc_Set-WinDefend ; break} 11 {sc_Set-RemoteMgmt ; break} 12 {sc_Set-RDP ; break} 13 {sc_Set-WindowsUpdate ; break} 14 {sc_Execute-WindowsUpdate ; break} 15 {sc_Logoff ; break} 16 {sc_Restart ; break} 17 {sc_Shutdown ; break} 18 {sc_Exit ; break} } } ######################################################## CHANGE DOMAIN/WORKGROUP ####################################################### function sc_Set-Domain ( ) { # RESETS VARIABLES FOR FUNCTION $DomOrWork = $null $DWname = $null $NewName = $null $ValidDW = $null $OutputText = $null # EXECUTES DOMAIN JOIN function sc_Join-Domain ( [parameter(Mandatory=$true)]$DName ) { # RESETS VARIABLES FOR FUNCTION $DCred = $null # DEFINES VALID COMPUTER CHARCATERS $Characters = "[][\\/;:*?`"`'<>|,~!@#$%^&.(){}_``=+ ]" # GETS CREDENTIALS AND NEW NAME $DCred = Get-Credential -Message "Specify an authorized domain\user" # GATHERS INPUT $NewName = $null $NewName = Read-Host "Enter new name for this computer (Blank = keep current name)" # THROWS ERROR MESSAGE AND RETURNS TO SET DOMAIN MENU If ($NewName -match $Characters) { Write-Host -ForegroundColor Red "Invalid characters used. The following characters are illegal:" Write-Host -ForegroundColor Yellow "$Characters" Write-Host -ForegroundColor Yellow "Returning to Set Domain menu..." Start-Sleep -Seconds 2 sc_Set-Domain } # THROWS ERROR MESSAGE AND RETURNS TO SET DOMAIN MENU If ($NewName.Length -ge 16) { Write-Host -ForegroundColor Red "Name is too long. A valid name must be 15 characters or shorter." Write-Host -ForegroundColor Yellow "Returning to Set Domain menu..." Start-Sleep 2 sc_Set-Domain } # THROWS ERROR MESSAGE AND RETURNS TO SET DOMAIN MENU If ($NewName -match "^\d+$") { Write-Host -ForegroundColor Red "Name may not contain only digits" Write-Host -ForegroundColor Yellow "Returning to Set Domain menu..." Start-Sleep -Seconds 2 sc_Set-Domain } # EXECUTES DOMAIN JOIN If ($NewName -eq "") { Add-Computer -DomainName $DName -Credential $DCred sc_Create-MainMenu } Else { Add-Computer -DomainName $DName -NewName $NewName -Credential $DCred sc_Create-MainMenu } } # EXECUTES WORKGROUP JOIN function sc_Join-Workgroup ( [parameter(Mandatory=$true)]$WName ) { # RESETS VARIABLES FOR FUNCTION $DCred = $null $DCheck = $null $NewName = $null # CHECKS IF CURRENTLY IN A DOMAIN AND GETS NEW NAME $DCheck = Get-WmiObject -Class Win32_ComputerSystem # DEFINES VALID COMPUTER CHARCATERS $Characters = "[][\\/;:*?`"`'<>|,~!@#$%^&.(){}_``=+ ]" # GATHERS INPUT $NewName = $null $NewName = Read-Host "Enter new name for this computer (Blank = keep current name)" # THROWS ERROR MESSAGE AND RETURNS TO SET DOMAIN MENU If ($NewName -match $Characters) { Write-Host -ForegroundColor Red "Invalid characters used. The following characters are illegal:" Write-Host -ForegroundColor Yellow "$Characters" Write-Host -ForegroundColor Yellow "Returning to Set Domain menu..." Start-Sleep -Seconds 2 sc_Set-Domain } # THROWS ERROR MESSAGE AND RETURNS TO SET DOMAIN MENU If ($NewName.Length -ge 16) { Write-Host -ForegroundColor Red "Name is too long. A valid name must be 15 characters or shorter." Write-Host -ForegroundColor Yellow "Returning to Set Domain menu..." Start-Sleep 2 sc_Set-Domain } # THROWS ERROR MESSAGE AND RETURNS TO SET DOMAIN MENU If ($NewName -match "^\d+$") { Write-Host -ForegroundColor Red "Name may not contain only digits" Write-Host -ForegroundColor Yellow "Returning to Set Domain menu..." Start-Sleep -Seconds 2 sc_Set-Domain } # IF IN A DOMAIN, GATHERS CREDS ; EXECUTES WORKGROUP JOIN If (($DCheck.DomainRole -ne 0) -and ($DCheck.DomainRole -ne 2)) { $DCred = Get-Credential -Message "Specify credentials to unjoin domain" If ($NewName -eq "") { Add-Computer -DomainName $WName -Credential $DCred sc_Create-MainMenu } Else { Add-Computer -DomainName $WName -NewName $NewName -Credential $DCred sc_Create-MainMenu } } Else { If ($NewName -eq "") { Add-Computer -DomainName $WName sc_Create-MainMenu } Else { Add-Computer -DomainName $WName -NewName $NewName sc_Create-MainMenu } } } $ValidDW = @(1,2,3) # GENERATES OUTPUT TEXT $OutputText = " ------ JOIN DOMAIN/WORKGROUP ------ 1) Join Domain 2) Join Workgroup 3) Return to main menu " # RETURNS TEXT DATA Write-Output $OutputText # GATHERS OPTION UNTIL VALID CHOICE IS MADE Do { $DomOrWork = $null $DomOrWork = Read-Host "Enter selection" } While ($ValidDW -notcontains $DomOrWork) # EXECUTES SELECTED OPTION Switch ($DomOrWork) { 1 {$DWname = Read-Host "Name of domain to join" ; sc_Join-Domain -DName $DWname ; break} 2 {$DWname = Read-Host "Name of workgroup to join" ; sc_Join-Workgroup -WName $DWname ; break} 3 {sc_Create-MainMenu ; break} } } ########################################################## CHANGE COMPUTER NAME ######################################################## function sc_Set-ComputerName ( ) { # RESETS VARIABLES FOR FUNCTION $NewName = $null $DCheck = $null $Characters = $null # CHECKS IF CURRENTLY IN A DOMAIN AND GETS NEW NAME $DCheck = Get-WmiObject -Class Win32_ComputerSystem # DEFINES VALID COMPUTER CHARCATERS $Characters = "[][\\/;:*?`"`'<>|,~!@#$%^&.(){}_``=+ ]" # GATHERS INPUT $NewName = $null $NewName = Read-Host "Enter new computer name (Blank=Cancel)" # IF BLANK RETURNS TO MAIN MENU If ($NewName -eq "") { sc_Create-MainMenu } # THROWS ERROR MESSAGE AND RETURNS TO MAIN MENU If ($NewName -match $Characters) { Write-Host -ForegroundColor Red "Invalid characters used. The following characters are illegal:" Write-Host -ForegroundColor Red "$($Characters.Substring(1,32))" Write-Host -ForegroundColor Yellow "Returning to main menu..." Start-Sleep -Seconds 2 sc_Create-MainMenu } # THROWS ERROR MESSAGE AND RETURNS TO MAIN MENU If ($NewName.Length -ge 16) { Write-Host -ForegroundColor Red "Name is too long. A valid name must be 15 characters or shorter." Write-Host -ForegroundColor Yellow "Returning to main menu..." Start-Sleep -Seconds 2 sc_Create-MainMenu } # THROWS ERROR MESSAGE AND RETURNS TO MAIN MENU If ($NewName -match "^\d+$") { Write-Host -ForegroundColor Red "Name may not contain only digits" Write-Host -ForegroundColor Yellow "Returning to main menu..." Start-Sleep -Seconds 2 sc_Create-MainMenu } # IF IN A DOMAIN, GATHERS CREDS ; CHANGES SYSTEM NAME If (($DCheck.DomainRole -ne 0) -and ($DCheck.DomainRole -ne 2)) { $DCred = Get-Credential -Message "Specify credentials to update computer object" Rename-Computer -NewName $NewName -DomainCredential $DCred sc_Create-MainMenu } Else { Rename-Computer -NewName $NewName sc_Create-MainMenu } } ######################################################## ADD LOCAL ADMINISTRATOR ####################################################### function sc_Add-LocalAdmin ( ) { # RESETS VARIABLES FOR FUNCTION $CompSys = $null $LocAdmin = $null $LocUser = $null $Pass = $null $OutputText = $null $Characters = $null # GATHERS DATA $CompSys = Get-WmiObject -Class Win32_ComputerSystem # DEFINES VALID COMPUTER CHARCATERS $Characters = "[][\\/:*?`"<>|,;@]" # GENERATES OUTPUT TEXT $OutputText = " In a domain environment, specify domain\username. In a workgroup environment, specify username. " # RETURNS TEXT DATA Write-Output $OutputText # GATHERS ADMIN ACCOUNT NAME $LocAdmin = Read-Host "Enter account to join local Administrators group (Blank=Cancel)" # ADDS ACCOUNT TO LOCAL ADMIN GROUP ; WILL CREATE USER IF IN A WORKGROUP AND USER DOESN'T EXIST If ($LocAdmin -ne "") { # WORKGROUP/NON-DOMAIN PROCESS If (($CompSys.DomainRole -eq 0) -or ($CompSys.DomainRole -eq 2)) { # ERRORS IF INVALID CHARACTERS ARE USED If ($LocAdmin -match $Characters) { Write-Host -ForegroundColor Yellow "Invalid characters used. The following characters are illegal:" Write-Host -ForegroundColor Yellow "$($Characters.Substring(1,14))" Write-Host -ForegroundColor Yellow "Returning to main menu..." Start-Sleep -Seconds 2 sc_Create-MainMenu } If ($LocAdmin.Length -ge 16) { Write-Host -ForegroundColor Yellow "Name is too long. A valid name must be 15 characters or shorter." Write-Host -ForegroundColor Yellow "Returning to main menu..." Start-Sleep -Seconds 2 sc_Create-MainMenu } # CHECKS FOR USER ACCOUNT, CREATES IF MISSING, OTHERWISE ADDS TO ADMINISTRATORS $LocUser = Get-LocalUser -Name $LocAdmin -ErrorAction SilentlyContinue If ($LocUser -eq $null) { $Pass = Read-Host -AsSecureString "Enter password for user account" New-LocalUser -Name $LocAdmin -Password $Pass | Add-LocalGroupMember -Group Administrators sc_Create-MainMenu } Else { Add-LocalGroupMember -Group Administrators -Member $LocAdmin sc_Create-MainMenu } # DOMAIN PROCESS } Else { # VALIDATES A DOMAIN WAS PROVIDED If ($LocAdmin.Split('\\')[1] -eq $null) { Write-Host -ForegroundColor Yellow "Domain systems may only add domain accounts." Write-Host -ForegroundColor Yellow "No domain provide in input. Returning to main menu..." Start-Sleep -Seconds 1 sc_Create-MainMenu } Add-LocalGroupMember -Group Administrators -Member $LocAdmin -Verbose sc_Create-MainMenu } } Else { sc_Create-MainMenu } } ###################################################### CONFIGURE DATE AND TIME ###################################################### function sc_Set-DateTime ( ) { # EXECUTES TIME/DATE CPL timedate.cpl sc_Create-MainMenu } ###################################################### CONFIGURE NETWORK SETTINGS ###################################################### function sc_Set-Network ( ) { # RESETS ALL VARIABLES FOR FUNCTION $AdapterArray = @() $NetAdapters = @() $NetChoice = $null $NetInput = $null $IP = $null # CONVERTS SUBNETS INTO PREFIXES AND PREFIXES INTO SUBNETS function sc_Convert-SubnetInfo ( [parameter(Mandatory=$false)]$Sub, [parameter(Mandatory=$false)]$Pre ) { # GENERATES OUTPUT TEXT [int]$cnt = 0 [string]$OutArr = "" [string]$BinaryOctet = $null [string]$BinaryAddress = $null [string]$Subnet = $null [string]$Prefix = $null # EXECUTES IF SUB WAS INPUTTED If ($Sub -ne $null) { # PROCESSES EACH OCTET SEPARATELY $Sub.Split('.') | Foreach { $BinaryOctet = [convert]::ToString($_,2) # IF OCTET IS 0, CREATES 8-BITS OF 0 If ($BinaryOctet -eq 0) { $BinaryOctet = "00000000" } # MERGES WITH EXISTING DATA $BinaryAddress = "$BinaryAddress" + "$BinaryOctet" } # COUNTS 1 BITS IN ADDRESS AND THEN OUTPUTS PREFIX $Prefix = ($BinaryAddress.ToCharArray() | Where {$_ -eq '1'}).count Return $Prefix } # EXECUTES IF PRE WAS INPUTTED If ($Pre -ne $null) { # ADDS A 1 AT THE BACK OF THE STRING UNTIL THE PREFIX NUMBER THEN ADDS A 0 UNTIL ALL 32 BITS ARE ACCOUNNTED FOR While ($cnt -lt 32) { If ($cnt -lt $Pre) { $OutArr = "$OutArr" + "1" } Else { $OutArr = "$OutArr" + "0" } $cnt++ } # ADDS '.' INTO THE BITS TO MAKE A BINARY ADDRESS $BinaryAddress = "$($OutArr.Substring(0,8)).$($OutArr.Substring(8,8)).$($OutArr.Substring(16,8)).$($OutArr.Substring(24,8))" $cnt = 0 # CONVERTS EACH BINARY OCTET TO DECIMAL $BinaryAddress.Split('.') | Foreach { $Octet = [convert]::ToInt32($_,2) If ($cnt -eq 0) { $Subnet = "$Octet" } Else { $Subnet = "$Subnet" + "." + "$Octet" } $cnt++ } # OUTPUTS SUBNET MASK Return $Subnet } } # PROVIDES THE INTERFACE AFTER ADAPTER IS SELECTED function sc_Modify-NetInterface ( [parameter(Mandatory=$true)][psobject]$Adapter ) { # RESETS ALL VARIABLES FOR FUNCTION $OutputText = $null $ValidNetConf = @() $NetConfChoice = $null $IPData = $null $cnt = 1 $ValidNetConf = @(1,2,3,4) # GATHERS INTERFACE IP DATA $IPData = sc_Get-NetInfo -Name $Adapter.Name # GENERATES OUTPUT TEXT $OutputText = " -------------------------------- $($Adapter.Name) Settings -------------------------------- $($IPData | Out-String) 1) Modify IPv4 Address Settings 2) Modify DNS Server Settings 3) Enable/Disable IPv6 4) Return to main menu " # RETURNS TEXT DATA Write-Output $OutputText # GATHERS INPUT UNTIL VALID OPTION IS SELECTED Do { $NetConfChoice = $null [int]$NetConfChoice = Read-Host "Enter selection" } While ($ValidNetConf -notcontains $NetConfChoice) # EXECUTES FUNCTIONS FOR PROCESSING CHANGES Switch ($NetConfChoice) { 1 {sc_Set-IPv4 -Data $IPData ; sc_Modify-NetInterface -Adapter $Adapter ; break} 2 {sc_Modify-DNSSettings -Data $IPData ; sc_Modify-NetInterface -Adapter $Adapter ; break} 3 {sc_Toggle-IPv6 -Adapter $IPData ; break} 4 {sc_Create-MainMenu ; break} } } # EXECUTES CHANGES TO IPV4 ADDRESSES function sc_Set-IPv4 ( [parameter(Mandatory=$true)]$Data ) { # RESETS ALL VARIABLES FOR FUNCTION $Prefix = $null $Octs = $null $IP = $null $Subnet = $null $Gateway = $null $ValidOcts = 0..255 $OutputText = $null $ValidDHCP = @(1,2,3) # GENERATES OUTPUT TEXT $OutputText = " ------ DHCP or STATIC IP ------ 1) Use DHCP 2) Use and set a static IP 3) Return to NIC Settings " # RETURNS TEXT DATA Write-Output $OutputText # GATHERS INPUT UNTIL VALID OPTION IS SELECTED Do { $DHCPChoice = $null $DHCPChoice = Read-Host "Enter selection" } While ($ValidDHCP -notcontains $DHCPChoice) # EXECUTES SELECTED OPTION If ($DHCPChoice -eq 1) { Set-NetIPInterface -InterfaceAlias $Data.Name -Dhcp Enabled Start-Sleep -Seconds 2 sc_Modify-NetInterface -Adapter $Data } ElseIf ($DHCPChoice -eq 2) { Set-NetIPInterface -InterfaceAlias $Data.Name -Dhcp Disabled $IP = Read-Host "Enter static IP address" $Octs = $IP.Split('.') # VALIDATES IP HAS 4 OCTETS If ($Octs.count -ne 4) { Write-Host -ForegroundColor Red "Invalid IP. Input must have 4 octects." sc_Modify-NetInterface -Adapter $Data } # VALIDATES IP VALUES FOR EACH OCTET Foreach ($Oct in $Octs) { If ($ValidOcts -notcontains $Oct) { Write-Host -ForegroundColor Red "Invalid IP. All octets must be between 0 and 255." sc_Modify-NetInterface -Adapter $Data } } $Subnet = Read-Host "Enter subnet mask (Blank = Default 255.0.0.0)" $Octs = $Subnet.Split('.') # VALIDATES IP HAS 4 OCTETS If ($Octs.count -ne 4) { Write-Host -ForegroundColor Red "Invalid IP. Input must have 4 octects." sc_Modify-NetInterface -Adapter $Data } # VALIDATES IP VALUES FOR EACH OCTET Foreach ($Oct in $Octs) { If ($ValidOcts -notcontains $Oct) { Write-Host -ForegroundColor Red "Invalid IP. All octets must be between 0 and 255." sc_Modify-NetInterface -Adapter $Data } } $Gateway = Read-Host "Enter default gateway" $Octs = $Gateway.Split('.') # VALIDATES IP HAS 4 OCTETS If (($Octs.count -ne 4) -and ($Octs -ne "")) { Write-Host -ForegroundColor Red "Invalid IP. Input must have 4 octects." sc_Modify-NetInterface -Adapter $Data } ElseIf ($Octs.count -eq 4) { # VALIDATES IP VALUES FOR EACH OCTET Foreach ($Oct in $Octs) { If ($ValidOcts -notcontains $Oct) { Write-Host -ForegroundColor Red "Invalid IP. All octets must be between 0 and 255." sc_Modify-NetInterface -Adapter $Data } } } # DELETES OLD IP DATA Remove-NetIPAddress -InterfaceAlias $Data.Name -Confirm:$false Remove-NetRoute -InterfaceAlias $Data.Name -AddressFamily IPv4 -NextHop $Data.DefaultGateway -Confirm:$false -ErrorAction SilentlyContinue| Out-Null # SETS NEW IP DATA New-NetIPAddress -InterfaceAlias $Data.Name -AddressFamily IPv4 -IPAddress $IP -PrefixLength (sc_Convert-SubnetInfo -Sub $Subnet) | Out-Null New-NetRoute -InterfaceAlias $Data.Name -AddressFamily IPv4 -NextHop $Gateway -DestinationPrefix "0.0.0.0/0" -Confirm:$false -ErrorAction SilentlyContinue| Out-Null sc_Modify-NetInterface -Adapter $Data } ElseIf ($DHCPChoice -eq 3) { sc_Modify-NetInterface -Adapter $Data } } # GATHERS IP INFO FOR AN INTERFACE function sc_Get-NetInfo ( [parameter(Mandatory=$true)]$Name ) { # RESETS ALL VARIABLES FOR FUNCTION $TempIPInfo = $null $IPv4 = $null $SM = $null $GW = $null $DNS1 = $null $DNS2 = $null $MAC = $null $DHCPStatus = $null $IPv6Status = $null $IPObject = $null # GATHERS ALL RELEVANT IP INFORMATION FROM EACH ADAPTER $TempIPInfo = Get-NetIPConfiguration -InterfaceAlias $Name $IPv4 = $TempIPInfo.IPv4Address.IPAddress $SM = sc_Convert-SubnetInfo -Pre $TempIPInfo.IPv4Address.PrefixLength $GW = $TempIPInfo.IPv4DefaultGateway.NextHop $DNS1 = (Get-DnsClientServerAddress -InterfaceAlias $Name -AddressFamily IPv4).ServerAddresses[0] $DNS2 = (Get-DnsClientServerAddress -InterfaceAlias $Name -AddressFamily IPv4).ServerAddresses[1] $MAC = (Get-NetAdapter -Name $Name).MacAddress $IPv6Status = (Get-NetAdapterBinding -Name $Name | Where {$_.ComponentID -eq "ms_tcpip6"}).Enabled # TRANSLATES PREFIX ORIGIN Switch ($TempIPInfo.IPv4Address.PrefixOrigin) { "Manual" {$DHCPStatus = "STATIC" ; break} "Dhcp" {$DHCPStatus = "DHCP" ; break} "WellKnown" {$DHCPStatus = "APIPA" ; break} } # GENERATES CUSTOM IP OBJECT $IPObject += New-Object -TypeName psobject -Property @{ Name = $Name Description = $TempIPInfo.InterfaceDescription IPv4 = $IPv4 SubnetMask = $SM DefaultGateway = $GW DNSServer1 = $DNS1 DNSServer2 = $DNS2 MAC = $MAC AddressAssignment = $DHCPStatus IPv6Enabled = $IPv6Status } # RETURNS IP DATA Return $IPObject | Select -Property Name,Description,AddressAssignment,MAC,IPv4,SubnetMask,DefaultGateway,DNSServer1,DNSServer2,IPv6Enabled } # MODIFIES DNS SETTINGS function sc_Modify-DNSSettings ( [parameter(Mandatory=$true)]$Data ) { # RESETS ALL VARIABLES FOR FUNCTION $DChoice = $null $PrefDNS = $null $AltDNS = $null $Octs = $null $OutputText = $null $ValidOcts = 0..255 $ValidD = @(1,2,3) # GENERATES OUTPUT TEXT $OutputText = " ------ DNS Settings ------ 1) Clear DNS Servers 2) Set DNS Servers 3) Back to NIC Settings " # RETURNS TEXT DATA Write-Output $OutputText # GATHERS INPUT UNTIL VALID OPTION IS SELECTED Do { $DChoice = $null $DChoice = Read-Host "Enter selection" } While ($ValidD -notcontains $DChoice) # EXECUTES SELECTED OPTION If ($DChoice -eq 1) { Set-DnsClientServerAddress -InterfaceAlias $Data.Name -ResetServerAddresses sc_Modify-NetInterface -Adapter $Data } ElseIf ($DChoice -eq 2) { # GATHERS DNS DATA $PrefDNS = Read-Host "Enter preferred DNS server" $Octs = $PrefDNS.Split('.') # VALIDATES IP HAS 4 OCTETS If ($Octs.count -ne 4) { Write-Host -ForegroundColor Red "Invalid IP. Input must have 4 octects." sc_Modify-NetInterface -Adapter $Data } # VALIDATES IP VALUES FOR EACH OCTET Foreach ($Oct in $Octs) { If ($ValidOcts -notcontains $Oct) { Write-Host -ForegroundColor Red "Invalid IP. All octets must be between 0 and 255." sc_Modify-NetInterface -Adapter $Data } } $AltDNS = Read-Host "Enter alternate DNS server (Blank for no entry)" $Octs = $PrefDNS.Split('.') # VALIDATES IP HAS 4 OCTETS If (($Octs.count -ne 4) -and ($AltDNS -ne "")) { Write-Host -ForegroundColor Red "Invalid IP. Input must have 4 octects." sc_Modify-NetInterface -Adapter $Data } ElseIf ($Octs.count -eq 4) { # VALIDATES IP VALUES FOR EACH OCTET Foreach ($Oct in $Octs) { If ($ValidOcts -notcontains $Oct) { Write-Host -ForegroundColor Red "Invalid IP. All octets must be between 0 and 255." sc_Modify-NetInterface -Adapter $Data } } } # EXECUTES DNS CHANGE Set-DnsClientServerAddress -InterfaceAlias $Data.Name -ServerAddresses ($PrefDNS,$AltDNS) sc_Modify-NetInterface -Adapter $Data } ElseIf ($DChoice -eq 3) { sc_Modify-NetInterface -Adapter $Adapter } } # ENABLES\DISABLES IPv6 ON AN INTERFACE function sc_Toggle-IPv6 ( [parameter(Mandatory=$true)]$Adapter ) { # RESETS ALL VARIABLES FOR FUNCTION $IPv6Choice = $null $OutputText = $null $ValidIPv6 = @(1,2,3) # GENERATES OUTPUT TEXT $OutputText = " ------ ENABLE/DISABLE IPv6 ------ 1) Disable IPv6 on this adapter 2) Enable IPv6 on this adapter 3) Back to NIC Settings " # RETURNS TEXT DATA Write-Output $OutputText # GATHERS INPUT UNTIL VALID OPTION IS SELECTED Do { $IPv6Choice = $null $IPv6Choice = Read-Host "Enter selection" } While ($ValidIPv6 -notcontains $IPv6Choice) # EXECUTES IPv6 SETTING Switch ($IPv6Choice) { 1 {Disable-NetAdapterBinding -Name $Adapter.Name -ComponentID ms_tcpip6 ; sc_Modify-NetInterface -Adapter $Adapter ; break} 2 {Enable-NetAdapterBinding -Name $Adapter.Name -ComponentID ms_tcpip6 ; sc_Modify-NetInterface -Adapter $Adapter ; break} 3 {sc_Modify-NetInterface -Adapter $Adapter ; break} } } # RESETS CNT VARIABLE $cnt = 1 # GATHERS ALL NETWORK ADAPTERS ON SERVER $Teams = Get-NetLbfoTeam $NetAdapters += Get-NetAdapter | Sort -Property Name | Foreach { If ($Teams.Members -notcontains $_.Name) { $IP = Get-NetIPConfiguration -InterfaceAlias $_.Name New-Object -TypeName psobject -Property @{ Name = $_.Name IPv4 = $IP.IPv4Address Description = $_.InterfaceDescription "#" = $cnt } } Else { New-Object -TypeName psobject -Property @{ Name = $_.Name IPv4 = "N/A" Description = "NIC Team Member" "#" = $cnt } } $cnt++ } $NetAdapters += New-Object -TypeName psobject -Property @{ Name = "Return to Main menu" IPv4 = "" Description = "" "#" = $cnt } # GENERATES OUTPUT TEXT $OutputText = " ----Network Adapter Settings---- Available Network Adapters " # RETURNS TEXT DATA AND BRIEF OF ADAPTER DATA AS STRING Write-Output $OutputText $NetAdapters | Select -Property "#",Name,IPv4,Description | Sort -Property "#" | Out-String # GATHERS INPUT UNTIL VALID OPTION IS SELECTED Do { $NetChoice = $null $NetChoice = Read-Host "Enter selection" # Ignores team members selections If ($Teams -ne $null) { If (($NetAdapters | Where {$_.Description -eq "NIC Team Member"})."#" -contains $NetChoice) { Write-Host -ForegroundColor Yellow "Due to NIC Teaming this interface is not allowed to be modified." Write-Host -ForegroundColor Yellow "Please select another." $NetChoice = $null } } If ($NetChoice -eq $NetAdapters.count) { sc_Create-MainMenu } } While ($NetAdapters."#" -notcontains $NetChoice) # GATHERS ONLY ADAPTER TO BE WORKED $NetInput = $NetAdapters | Where {$_."#" -like "$NetChoice"} # EXECUTES ADAPTER SPECIFIC INTERFACE sc_Modify-NetInterface -Adapter $NetInput } ###################################################### CONFIGURES NIC TEAMING ###################################################### function sc_Config-NICTeaming ( ) { # RESETS ALL VARIABLES FOR FUNCTION $NICTeams = $null $ValidNT = @() $NTChoice = $null $OutputText = $null $NICOutput = $null function sc_Create-NICTeam ( [Parameter(Mandatory=$true)]$Teams ) { # RESETS ALL VARIABLES FOR FUNCTION $AvailNics = $null $TeamName = $null $NICChoice = $null $Model = $null $OutputText = $null $NicInput = $null $ValidTM = $null $OutputText2 = $null $TMChoice = $null $ValidLBA = $null $OutputText3 = $null $LBAChoice = $null $cnt = 1 # GATHERS ONLY VALID ADAPTERS If ($Teams -eq "NO TEAMS") { $AvailNics = Get-NetAdapter | Sort -Property Name } Else { $AvailNics = Get-NetAdapter | Sort -Property Name | Where {($Teams.Members -notcontains $_.Name) -and ($_.InterfaceDescription -notmatch ` "Microsoft Network Adapter Multiplexor Driver")} } If ($AvailNics.count -eq 0) { Write-Host -ForegroundColor Yellow "No NICs are available for teaming." Start-Sleep -Seconds 1 sc_Config-NICTeaming } Else { Foreach ($AvailNic in $AvailNics) { $AvailNic | Add-Member -MemberType NoteProperty -Name "#" -Value $cnt $cnt++ } } # GATHERS TEAM NAME "" $TeamName = Read-Host "Input NIC Team Name" # GENERATES OUTPUT TEXT $OutputText = " ----Select First Team Member---- " # RETURNS TEXT DATA AND BRIEF OF ADAPTER DATA AS STRING Write-Output $OutputText $AvailNics | Select -Property "#",Name | Sort -Property "#" | Out-String # GATHERS INPUT UNTIL VALID OPTION IS SELECTED Do { $NICChoice = $null $NICChoice = Read-Host "Enter selection" } While ($AvailNics."#" -notcontains $NICChoice) # GATHERS ONLY ADAPTER TO BE WORKED $NicInput = $AvailNics | Where {$_."#" -like "$NICChoice"} # GATHERS COMPUTER MODEL $Model = Get-WmiObject -Class Win32_ComputerSystem | Select -Property Model # IF VIRTUAL MACHINE SETS ONLY POSSIBLE TEAM MODE OTHERWISE GATHERS INPUT If (($Model.Model -match "Virtual Machine") -or ($Model.Model -match "VMware")) { $TeamMode = "SwitchIndependent" } Else { # DEFINE VALID INPUT $ValidTM = @(1,2,3) # GENERATES OUTPUT TEXT $OutputText2 = " -------Select Teaming Mode------ 1) Switch Independent (default in GUI) 2) LACP 3) Static " # RETURNS TEXT Write-Output $OutputText2 # GATHERS INPUT UNTIL VALID OPTION IS SELECTED Do { $TMChoice = $null $TMChoice = Read-Host "Enter selection" } While ($ValidTM -notcontains $TMChoice) # CONVERTS TMCHOICE TO VALID COMMAND STRING Switch ($TMChoice) { 1 {$TeamMode = "SwitchIndependent" ; break} 2 {$TeamMode = "Lacp" ; break} 3 {$TeamMode = "Static" ; break} } } # DEFINE VALID INPUT $ValidLBA = @(1,2,3,4,5) # GENERATES OUTPUT TEXT $OutputText3 = " --Select Load Balancing Algorithm-- 1) Transport Ports (default in GUI) 2) Dynamic 3) Hyper-V Port 4) IP Addresses 5) MAC Addresses " # RETURNS TEXT Write-Output $OutputText3 # GATHERS INPUT UNTIL VALID OPTION IS SELECTED Do { $LBAChoice = $null $LBAChoice = Read-Host "Enter selection" } While ($ValidLBA -notcontains $LBAChoice) # CONVERTS LBACHOICE TO VALID COMMAND STRING Switch ($LBAChoice) { 1 {$LBA = "TransportPorts" ; break} 2 {$LBA = "Dynamic" ; break} 3 {$LBA = "HyperVPort" ; break} 4 {$LBA = "IPAddresses" ; break} 5 {$LBA = "MacAddresses" ; break} } # EXECUTES NIC TEAM CREATION AND THEN RETURNS TO PREVIOUS MENU New-NetLbfoTeam -Name $TeamName -TeamMembers $NicInput.Name -TeamingMode $TeamMode -LoadBalancingAlgorithm $LBA -Confirm:$false sc_Config-NICTeaming } function sc_Add-NICTeamMember ( [Parameter(Mandatory=$true)]$Teams ) { # RESETS ALL VARIABLES FOR FUNCTION $AvailNics = $null $NTChoice = $null $TeamInput = $null $NICChoice = $null $OutputText = $null $NicInput = $null $OutputText2 = $null $ValidNM = @() $NMChoice = $null $OutputText3 = $null $ModeInput = $null $cnt = 1 # VALIDATES THAT THERE ARE AVAILABLE TEAMS If ($Teams -eq "NO TEAMS") { Write-Host -ForegroundColor Yellow "No NIC Teams are currently created." Start-Sleep -Seconds 1 sc_Config-NICTeaming } Else { $Teams = $Teams | Sort -Property Name Foreach ($Team in $Teams) { $Team | Add-Member -MemberType NoteProperty -Name "#" -Value $cnt -Force $cnt++ } } # GATHERS ONLY VALID ADAPTERS $cnt = 1 $AvailNics = Get-NetAdapter | Where {($Teams.Members -notcontains $_.Name) -and ($_.InterfaceDescription -notmatch ` "Microsoft Network Adapter Multiplexor Driver")} # VALIDATES THAT THERE ARE AVAILABLE NICS, AND GENERATES OUTPUT If ($AvailNics.count -eq 0) { Write-Host -ForegroundColor Yellow "No NICs are available for teaming." Start-Sleep -Seconds 1 sc_Config-NICTeaming } Else { $AvailNics = $AvailNics | Sort -Property Name Foreach ($AvailNic in $AvailNics) { $AvailNic | Add-Member -MemberType NoteProperty -Name "#" -Value $cnt $cnt++ } } # GENERATES OUTPUT TEXT $OutputText = " ---Select NIC Team to Modify---- " # RETURNS TEAM DATA AS STRING Write-Output $OutputText $Teams | Select -Property "#",Name,Members | Out-String # GATHERS INPUT UNTIL VALID OPTION IS SELECTED Do { $NTChoice = $null $NTChoice = Read-Host "Enter selection" } While ($Teams."#" -notcontains $NTChoice) # GATHERS ONLY ADAPTER TO BE WORKED $TeamInput = $Teams | Where {$_."#" -like "$NTChoice"} # GENERATES OUTPUT TEXT $OutputText2 = " -----Select NIC to Join Team---- " # RETURNS TEXT DATA AND BRIEF OF ADAPTER DATA AS STRING Write-Output $OutputText2 $AvailNics | Select -Property "#",Name | Sort -Property "#" | Out-String # GATHERS INPUT UNTIL VALID OPTION IS SELECTED Do { $NICChoice = $null $NICChoice = Read-Host "Enter selection" } While ($AvailNics."#" -notcontains $NICChoice) # GATHERS ONLY ADAPTER TO BE WORKED $NicInput = $AvailNics | Where {$_."#" -like "$NICChoice"} # DEFINES VALID INPUT $ValidNM = @(1,2) # GENERATES OUTPUT TEXT $OutputText3 = " ----Select Mode for Adapter----- 1) Active 2) Standby " # RETURNS TEXT DATA AND BRIEF OF ADAPTER DATA AS STRING Write-Output $OutputText3 # GATHERS INPUT UNTIL VALID OPTION IS SELECTED Do { $NMChoice = $null $NMChoice = Read-Host "Enter selection" } While ($ValidNM -notcontains $NMChoice) # CONVERTS NMCHOICE TO VALID COMMAND STRING Switch ($NMChoice) { 1 {$ModeInput = "Active" ; break} 2 {$ModeInput = "Standby" ; break} } # EXECUTES NIC TEAM MEMBER ADD AND THEN RETURNS TO PREVIOUS MENU Add-NetLbfoTeamMember -Name $NicInput.Name -Team $TeamInput.Name -AdministrativeMode $ModeInput -Confirm:$false | Out-Null sc_Config-NICTeaming } function sc_Remove-NICTeamMember ( [Parameter(Mandatory=$true)]$Teams ) { # RESETS ALL VARIABLES FOR FUNCTION $NTChoice = $null $TeamInput = $null $SelectedTeam = $null $TeamMembers = @() $NICChoice = $null $OutputText = $null $NicInput = $null $OutputText2 = $null $cnt = 1 # VALIDATES THAT THERE ARE AVAILABLE TEAMS If ($Teams -eq "NO TEAMS") { Write-Host -ForegroundColor Yellow "No NIC Teams are currently created." Start-Sleep -Seconds 1 sc_Config-NICTeaming } Else { $Teams = $Teams | Sort -Property Name Foreach ($Team in $Teams) { $Team | Add-Member -MemberType NoteProperty -Name "#" -Value $cnt -Force $cnt++ } } # GENERATES OUTPUT TEXT $OutputText = " ---Select NIC Team to Modify---- " # RETURNS TEAM DATA AS STRING Write-Output $OutputText $Teams | Select -Property "#",Name,Members | Out-String # GATHERS INPUT UNTIL VALID OPTION IS SELECTED Do { $NTChoice = $null $NTChoice = Read-Host "Enter selection" } While ($Teams."#" -notcontains $NTChoice) # GATHERS ONLY ADAPTER TO BE WORKED $TeamInput = $Teams | Where {$_."#" -like "$NTChoice"} # GATHERS NIC TEAM MEMBERS $cnt = 1 $SelectedTeam = ($Teams | Where {$_.Name -match $TeamInput.Name}).Members | Sort # VALIDATES THAT THERE ARE MULTIPLE NICS IN TEAM If ($SelectedTeam.count -eq 1) { Write-Host -ForegroundColor Yellow "Only 1 member in team. Use `'Delete NIC Team`' option." Start-Sleep -Seconds 1 sc_Config-NICTeaming } Else { Foreach ($Member in $SelectedTeam) { $TeamMembers += New-Object -TypeName psobject -Property @{ "#" = $cnt Name = $Member } $cnt++ } } # GENERATES OUTPUT TEXT $OutputText2 = " ---Select NIC to Remove from Team-- " # RETURNS TEXT DATA AND BRIEF OF ADAPTER DATA AS STRING Write-Output $OutputText2 $TeamMembers | Select -Property "#",Name | Sort -Property "#" | Out-String # GATHERS INPUT UNTIL VALID OPTION IS SELECTED Do { $NICChoice = $null $NICChoice = Read-Host "Enter selection" } While ($TeamMembers."#" -notcontains $NICChoice) # GATHERS ONLY ADAPTER TO BE WORKED $NicInput = $TeamMembers | Where {$_."#" -like "$NICChoice"} # EXECUTES NIC TEAM MEMBER REMOVAL AND THEN RETURNS TO PREVIOUS MENU Remove-NetLbfoTeamMember -Name $NicInput.Name -Team $TeamInput.Name -Confirm:$false | Out-Null sc_Config-NICTeaming } function sc_Remove-NICTeam ( [Parameter(Mandatory=$true)]$Teams ) { # RESETS ALL VARIABLES FOR FUNCTION $NTChoice = $null $TeamInput = $null $OutputText = $null $cnt = 1 # VALIDATES THAT THERE ARE AVAILABLE TEAMS If ($Teams -eq "NO TEAMS") { Write-Host -ForegroundColor Yellow "No NIC Teams are currently created." Start-Sleep -Seconds 1 sc_Config-NICTeaming } Else { $Teams = $Teams | Sort -Property Name Foreach ($Team in $Teams) { $Team | Add-Member -MemberType NoteProperty -Name "#" -Value $cnt -Force $cnt++ } } # GENERATES OUTPUT TEXT $OutputText = " ---Select NIC Team to Delete---- " # RETURNS TEAM DATA AS STRING Write-Output $OutputText $Teams | Select -Property "#",Name,Members | Out-String # GATHERS INPUT UNTIL VALID OPTION IS SELECTED Do { $NTChoice = $null $NTChoice = Read-Host "Enter selection" } While ($Teams."#" -notcontains $NTChoice) # GATHERS ONLY ADAPTER TO BE WORKED $TeamInput = $Teams | Where {$_."#" -like "$NTChoice"} # EXECUTES NIC TEAM DELETION AND THEN RETURNS TO PREVIOUS MENU Remove-NetLbfoTeam -Name $TeamInput.Name -Confirm:$false sc_Config-NICTeaming } # GATHERS ALL NIC TEAMS $NICTeams = Get-NetLbfoTeam # GATHERS NIC TEAM INFO If ($NICTeams -eq $null) { $NICOutput = "**No NIC Teams are configured**" $NICTeams = "NO TEAMS" } Else { $NICOutput = $NICTeams | Select -Property Name,Members,Status | Out-String } # DEFINES VALID INPUTS $ValidNT = @(1,2,3,4,5) # GENERATES OUTPUT TEXT $OutputText = " -------------------------------- CURRENT TEAMS -------------------------------- $NICOutput -----Configuration Options------ 1) Create NIC Team 2) Add Member to NIC Team 3) Remove Member of NIC Team 4) Delete NIC Team 5) Return to main menu " # RETURNS TEXT DATA Write-Output $OutputText # GATHERS INPUT UNTIL VALID OPTION IS SELECTED Do { $NTChoice = $null $NTChoice = Read-Host "Enter selection" } While ($ValidNT -notcontains $NTChoice) # EXECUTES CHOSEN SUB-FUNCTION Switch ($NTChoice) { 1 {sc_Create-NICTeam -Teams $NICTeams ; break} 2 {sc_Add-NICTeamMember -Teams $NICTeams ; break} 3 {sc_Remove-NICTeamMember -team $NICTeams ; break} 4 {sc_Remove-NICTeam -Teams $NICTeams ; break} 5 {sc_Create-MainMenu ; break} } } ##################################################### CONFIGURE FIREWALL PROFILES ###################################################### function sc_Set-Firewall ( ) { # RESETS ALL VARIABLES FOR FUNCTION $DomFW = $null $PriFW = $null $PubFW = $null $OutputText = $null $ValidFW = @() $FWChoice = $null # FUNCTION TO TOGGLE A FIREWALL PROFILE function sc_Toggle-Firewall ( [parameter(Mandatory=$true)]$Profile, [parameter(Mandatory=$true)]$Status ) { If ($Status -eq "Enabled") { Set-NetFirewallProfile -Name $Profile -Enabled False | Out-Null sc_Set-Firewall } Else { Set-NetFirewallProfile -Name $Profile -Enabled True | Out-Null sc_Set-Firewall } } # DEFINES VALID INPUTS $ValidFW = @(1,2,3,4) # GATHERS STATUS OF EACH PROFILE If ((Get-NetFirewallProfile -Name Domain).Enabled) {$DomFW = "Enabled"} Else {$DomFW = "Disabled"} If ((Get-NetFirewallProfile -Name Private).Enabled) {$PriFW = "Enabled"} Else {$PriFW = "Disabled"} If ((Get-NetFirewallProfile -Name Public).Enabled) {$PubFW = "Enabled"} Else {$PubFW = "Disabled"} # GENERATES OUTPUT TEXT $OutputText = " --- TOGGLE FIREWALL --- 1) Domain: $DomFW 2) Private: $PriFW 3) Public: $PubFW 4) Return to main menu " # RETURNS TEXT DATA Write-Output $OutputText # GATHERS INPUT UNTIL VALID OPTION IS SELECTED Do { $FWChoice = $null $FWChoice = Read-Host "Enter selection" } While ($ValidFW -notcontains $FWChoice) Switch ($FWChoice) { 1 {sc_Toggle-Firewall -Profile "Domain" -Status $DomFW ; break} 2 {sc_Toggle-Firewall -Profile "Private" -Status $PriFW ; break} 3 {sc_Toggle-Firewall -Profile "Public" -Status $PubFW ; break} 4 {sc_Create-MainMenu ; break} } } ######################################################### CONFIGURE TELEMETRY ########################################################## function sc_Set-Telemetry ( ) { # GENERATES OUTPUT TEXT $ValidTel = $null $TelReg = $null $OutputText = $null $TelChoice = $null # DEFINES VALID OPTIONS $ValidTel = @(1,2,3,4,5) # GATHERS SETTING IF SET BY GROUP POLICY $TelReg = (Get-ItemProperty -Path "HKLM:\\SOFTWARE\Policies\Microsoft\Windows\DataCollection").AllowTelemetry # EXITS FUNCTION IF CONTROLLED BY GROUP POLICY If ($TelReg -ne $null) { Write-Host "Telemetry settings are controlled by Group Policy. Returning to main menu..." Start-Sleep -Seconds 3 sc_Create-MainMenu } # GENERATES OUTPUT TEXT $OutputText = " Available telemetry settings: 1) Security 2) Basic 3) Enhanced 4) Full 5) Return to main menu " # RETURNS TEXT DATA Write-Output $OutputText # GATHERS OPTION UNTIL VALID CHOICE IS MADE Do { $TelChoice = $null $TelChoice = Read-Host "Enter selection" } While ($ValidTel -notcontains $TelChoice) # EXECUTES TELEMETRY ADJUSTMENT Switch ($TelChoice) { 1 {Set-ItemProperty -Path "HKLM:\\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\DataCollection" -Name AllowTelemetry -Value 0 ; sc_Create-MainMenu ; break} 2 {Set-ItemProperty -Path "HKLM:\\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\DataCollection" -Name AllowTelemetry -Value 1 ; sc_Create-MainMenu ; break} 3 {Set-ItemProperty -Path "HKLM:\\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\DataCollection" -Name AllowTelemetry -Value 2 ; sc_Create-MainMenu ; break} 4 {Set-ItemProperty -Path "HKLM:\\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\DataCollection" -Name AllowTelemetry -Value 3 ; sc_Create-MainMenu ; break} 5 {sc_Create-MainMenu ; break} } } ###################################################### EXECUTE WINDOWS ACTIVATION ###################################################### function sc_Set-WinAct ( ) { # RESETS VARIABLES FOR FUNCTION $OutputText = $null $ValidWA = $null $WAChoice = $null $Key = $null # SETS VALID OPTIONS $ValidWA = @(1,2,3,4) # GENERATES OUTPUT TEXT $OutputText = " -- Windows Activation -- 1) Display License Info 2) Activate Windows 3) Install Product Key 4) Return to main menu " # RETURNS TEXT DATA Write-Output $OutputText # GATHERS OPTION UNTIL VALID CHOICE IS SELECTED Do { $WAChoice = Read-Host "Enter selection" } While ($ValidWA -notcontains $WAChoice) # EXECUTES SELECTED OPTION Switch ($WAChoice) { 1 {slmgr /dli ; sc_Set-WinAct ; break} 2 {Write-Host -ForegroundColor Yellow "Processing activation attempt. This may take awhile..." ; slmgr /ato ; sc_Set-WinAct ; break} 3 {$Key = Read-Host "Input license key" ; slmgr /ipk $Key ; sc_Set-WinAct ; break} 4 {sc_Create-MainMenu ; break} } } ###################################################### CONFIGURE WINDOWS DEFENDER ###################################################### function sc_Set-WinDefend ( ) { # RESETS VARIABLES FOR FUNCTION $OutputText = $null $RTPStatus = $null $CBPStatus = $null $ASSStatus = $null $WDChoice = $null $ValidWD = $null # GATHERS WINDOWS DEFENDER SETTINGS $MPInfo = Get-MpPreference # TRANSLATES DATA FOR REAL-TIME PROTECTION STATUS If ($MPInfo.DisableRealtimeMonitoring -eq $false) { $RTPStatus = "ON" } ElseIf ($MPInfo.DisableRealtimeMonitoring -eq $true) { $RTPStatus = "OFF" } Else { $RTPStatus = "Query failed" } # TRANSLATES DATA FOR CLOUD-BASED PROTECTION STATUS If ($MPInfo.MAPSReporting -eq 2) { $CBPStatus = "ON" } ElseIf ($MPInfo.MAPSReporting -eq 0) { $CBPStatus = "OFF" } Else { $CBPStatus = "Query failed" } # TRANSLATES DATA FOR AUTOMATIC SAMPLE SUBMISSION STATUS If ($MPInfo.SubmitSamplesConsent -eq 1) { $ASSStatus = "ON" } ElseIf ($MPInfo.SubmitSamplesConsent -eq 0) { $ASSStatus = "OFF" } Else { $ASSStatus = "Query failed" } # SETS VALID OPTIONS $ValidWD = @(1,2,3,4) # GENERATES OUTPUT TEXT $OutputText = " ---------------------------------- Configure Windows Defender ---------------------------------- Real-time Protection: $RTPStatus Cloud-based Protection: $CBPStatus Automatic Sample Submission: $ASSStatus 1) Toggle Real-time Protection 2) Toggle Cloud-base Protection 3) Toggle Automatic Sample Submission 4) Return to main menu " # RETURNS TEXT DATA Write-Output $OutputText # GATHERS OPTION UNTIL VALID CHOICE IS SELECTED Do { $WDChoice = Read-Host "Enter selection" } While ($ValidWD -notcontains $WDChoice) # EXECUTES SELECTED OPTION Switch ($WDChoice) { 1 {If ($RTPStatus -eq "ON") {Set-MpPreference -DisableRealtimeMonitoring $true ; sc_Set-WinDefend} ElseIf ($RTPStatus -eq "OFF") ` {Set-MpPreference -DisableRealtimeMonitoring $false ; sc_Set-WinDefend} Else ` {Write-Host -ForegroundColor Yellow "Cannot toggle due to failed query" ; sc_Set-WinDefend} ; break} 2 {If ($CBPStatus -eq "ON") {Set-MpPreference -MAPSReporting 0 ; sc_Set-WinDefend} ElseIf ($CBPStatus -eq "OFF") ` {Set-MpPreference -MAPSReporting 2 ; sc_Set-WinDefend} Else ` {Write-Host -ForegroundColor Yellow "Cannot toggle due to failed query" ; sc_Set-WinDefend} ; break} 3 {If ($ASSStatus -eq "ON") {Set-MpPreference -SubmitSamplesConsent 0 ; sc_Set-WinDefend} ElseIf ` ($ASSStatus -eq "OFF") {Set-MpPreference -SubmitSamplesConsent 1 ; sc_Set-WinDefend} Else ` {Write-Host -ForegroundColor Yellow "Cannot toggle due to failed query" ; sc_Set-WinDefend} ; break} 4 {sc_Create-MainMenu ; break} } } ############################################################# CONFIGURE REMOTE MANAGEMENT ############################################################ function sc_Set-RemoteMgmt ( ) { # RESETS ALL VARIABLES FOR FUNCTION $RCheck = $null $RChoice = $null $RValid = $null $OutputText = $null # GATHERS STATUS AND VALID OPTIONS $RCheck = Configure-SMRemoting.exe -GET $RValid = @(1,2,3,4) # GENERATES OUTPUT TEXT $OutputText = " ---------------------------------- Configure Remote Management ---------------------------------- Current Status: $RCheck 1) Enable Remote Management 2) Disable Remote Management 3) Enable Server Response to PING 4) Return to main menu " # RETURNS TEXT DATA Write-Output $OutputText # GATHER INPUT UNTIL VALID OPTION Do { $RChoice = $null $RChoice = Read-Host "Enter selection" } While ($RValid -notcontains $RChoice) # EXECUTES SELECTED OPTION Switch ($RChoice) { 1 {Write-Host "Enabling Remote Management..." ; Configure-SMRemoting.exe -ENABLE ; sc_Set-RemoteMgmt ; break} 2 {Write-Host "Disabling Remote Management..." ; Configure-SMRemoting.exe -DISABLE ; sc_Set-RemoteMgmt ; break} 3 {Write-Host "Enabling PING requests..." ; Get-NetFirewallRule -DisplayName "File and Printer Sharing (Echo Request - ICMPv?-In" | Enable-NetFirewallRule ; sc_Set-RemoteMgmt ; break} 4 {sc_Create-MainMenu ; break} } } ############################################################# CONFIGURE RDP ############################################################ function sc_Set-RDP ( ) { # WHEN ENABLING RDP SETS AUTHENTICATION REQUIREMENT function sc_Set-SecureLevel ( ) { # RESETS ALL VARIABLES FOR FUNCTION $OutputText = $null $SChoice = $null $ValidS = $null # SETS VALID OPTIONS $ValidS = @(1,2,3) # GENERATES OUTPUT TEXT $OutputText = " ------ RDP Security Level ------ 1) Allow only clients running Remote Desktop with Network Level Authentication (more secure) 2) Allow clients running any version of Remote Desktop (less secure) 3) Return to main menu " # RETURNS TEXT DATA Write-Output $OutputText # GATHERS OPTION UNTIL VALID CHOICE IS MADE Do { $SChoice = $null $SChoice = Read-Host "Enter selection" } While ($ValidS -notcontains $SChoice) # EXECUTES SELECTED OPTION Switch ($SChoice) { 1 {Set-ItemProperty -Path "HKLM:\\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-TCP" -Name UserAuthentication -Value 1 ; sc_Create-MainMenu ; break} 2 {Set-ItemProperty -Path "HKLM:\\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-TCP" -Name UserAuthentication -Value 0 ; sc_Create-MainMenu ; break} 3 {sc_Create-MainMenu ; break} } } # SETS VALID OPTIONS $RDPValid = @(1,2,3) # GENERATES OUTPUT TEXT $OutputText = " ------ RDP Settings ------ 1) Enable RDP 2) Disable RDP 3) Return to main menu " # RETURNS TEXT DATA Write-Output $OutputText # GATHERS OPTION UNTIL VALID CHOICE IS MADE Do { $RDPChoice = $null $RDPChoice = Read-Host "Enter selection" } While ($RDPValid -notcontains $RDPChoice) # EXECUTES SELECTED OPTION Switch ($RDPChoice) { 1 {Set-ItemProperty -Path "HKLM:\\SYSTEM\CurrentControlSet\Control\Terminal Server" -Name fDenyTSConnections -Value 0 ; Write-Host "Enabling RDP..." ; sc_Set-SecureLevel ; break} 2 {Set-ItemProperty -Path "HKLM:\\SYSTEM\CurrentControlSet\Control\Terminal Server" -Name fDenyTSConnections -Value 1 ; Write-Host "Disabling RDP..." ; sc_Create-MainMenu ; break} 3 {sc_Create-MainMenu ; break} } } ####################################################### CONFIGURE WINDOWS UPDATES ###################################################### function sc_Set-WindowsUpdate ( ) { # RESETS ALL VARIABLES FOR FUNCTION $AU = $null $NoAU = $null $WU = $null $WUChoice = $null $OutputText = $null $ValidWU = $null # GATHERS WINDOWS UPDATE DATA $AU = Get-ItemProperty -Path "HKLM:\\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" $NoAU = $AU.NoAutoUpdate $AU = $AU.AUOptions # TRANSLATES REGISTRY FOR WINDOWS UPDATE TO USER FRIENDLY OUTPUT Switch ($AU) { $null {If ($NoAU -eq 1) {$WU = "Manual"} ElseIf ($NoAU -eq $null) {$WU = "Failed Query"} ; break} 1 {$WU = "Never check for updates" ; break} 2 {$WU = "Notify before download" ; break} 3 {$WU = "DownloadOnly" ; break} 4 {$WU = "Automatic" ; break} } # SETS VALID OPTIONS $ValidWU = @(1,2,3,4) # RETURNS WINDOWS UPDATE STATUS $OutputText = " ------ WINDOWS UPDATE SETTINGS ------ Windows Update currently set to: $WU 1) Set to Automatic 2) Set to DownloadOnly 3) Set to Manual 4) Return to main menu " # RETURNS TEXT DATA Write-Output $OutputText # GATHERS INPUT UNTIL VALID OPTION IS SELECTED Do { $WUChoice = $null $WUChoice = Read-Host "Enter selection" } While ($ValidWU -notcontains $WUChoice) # EXECUTES SELECTED OPTION Switch ($WUChoice) { 1 { Stop-Service -Name wuauserv Remove-ItemProperty -Path "HKLM:\\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name NoAutoUpdate -ErrorAction SilentlyContinue Remove-ItemProperty -Path "HKLM:\\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name AUOptions -ErrorAction SilentlyContinue New-ItemProperty -Path "HKLM:\\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name AUOptions -Value 4 | Out-Null Start-Service -Name wuauserv sc_Create-MainMenu break } 2 { Stop-Service -Name wuauserv Remove-ItemProperty -Path "HKLM:\\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name NoAutoUpdate -ErrorAction SilentlyContinue Remove-ItemProperty -Path "HKLM:\\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name AUOptions -ErrorAction SilentlyContinue New-ItemProperty -Path "HKLM:\\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name AUOptions -Value 3 | Out-Null Start-Service -Name wuauserv sc_Create-MainMenu break } 3 { Stop-Service -Name wuauserv Remove-ItemProperty -Path "HKLM:\\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name AUOptions -ErrorAction SilentlyContinue New-ItemProperty -Path "HKLM:\\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name NoAutoUpdate -Value 1 | Out-Null Start-Service -Name wuauserv sc_Create-MainMenu break } 4 {sc_Create-MainMenu ; break} } } ######################################################## EXECUTE WINDOWS UPDATES ####################################################### function sc_Execute-WindowsUpdate ( ) { # RESETS ALL VARIABLES FOR FUNCTION $UpdateSession = $null $UpdateSearcher = $null $SearchResults = $null $cnt = $null $UpdateList = @() $UpdateSelection = $null $UpdatesToDownload = $null $UTitle = $null $Update = $null $Downloader = $null $UpdatesToInstall = $null $Installer = $null $InstallationResult = $null # EXECUTES SYSTEM SCAN FOR RELAVENT PATCHES Write-Host "Beginning system scan. This may take a while..." $UpdateSession = New-Object -ComObject Microsoft.Update.Session $UpdateSearcher = $UpdateSession.CreateUpdateSearcher() $SearchResults = $UpdateSearcher.Search("IsInstalled=0 and Type='Software'") # CREATES OUTPUT OBJECT FOR EACH REQUIRED PATCH If ($SearchResults.Updates.Count -eq 0) { "" Write-Host -ForegroundColor Yellow "System is up-to-date. Returning to main menu..." Start-Sleep -Seconds 3 sc_Create-MainMenu } $cnt = 1 $SearchResults.Updates | Foreach {$UpdateList += New-Object -TypeName psobject -Property @{ SelNumber = $cnt Title = $_.Title Description = "$cnt) $($_.Title)" } $cnt++ } # RETURNS TEXT DATA "" $UpdateList.Description "" # GATHERS OPTION UNTIL VALID CHOICE IS MADE Do { $UpdateSelection = $null $UpdateSelection = Read-Host "Input number to install specific patch or `'A`' for all (Blank=Cancel)" If ($UpdateSelection -eq "") { Write-Host "Cancelling Windows Update..." sc_Create-MainMenu } } While (($UpdateSelection -notlike 'A') -and (($UpdateList | Where {$_.SelNumber -eq $UpdateSelection}) -eq $null)) # FILTERS TO ONLY SELECTED UPDATES $UpdatesToDownload = New-Object -ComObject Microsoft.Update.UpdateColl If ($UpdateSelection -like 'A') { Foreach ($KB in $SearchResults.Updates) { $UpdatesToDownload.Add($KB) | Out-Null } } Else { $UTitle = ($UpdateList | Where {$_.SelNumber -eq $UpdateSelection}).Title $Update = $SearchResults.Updates | Where {$_.Title -eq $UTitle} $UpdatesToDownload.Add($Update) | Out-Null } # EXECUTES DOWNLOAD OF ALL SELECTED UPDATES $Downloader = $UpdateSession.CreateUpdateDownloader() $Downloader.Updates = $UpdatesToDownload "" Write-Host "Beginning download of patches. This may take a while..." $Downloader.Download() | Out-Null # FILTERS TO ONLY DOWNLOADED UPDATES $UpdatesToInstall = New-Object -ComObject Microsoft.Update.UpdateColl Foreach ($KB in $SearchResults.Updates) { If ($KB.IsDownloaded -eq $true) { $UpdatesToInstall.Add($KB) | Out-Null } Else { Write-Host -ForegroundColor Red "$($KB.Title) failed to download. Skipping..." } } # EXECUTES INSTALLATION OF ALL DOWNLOADED UPDATES $Installer = $UpdateSession.CreateUpdateInstaller() $Installer.Updates = $UpdatesToInstall Write-Host "Beginning installation of patches. This may take awhile..." $InstallationResult = $Installer.Install() # REUTRNS STATUS OF ALL UPDATES ATTEMPTED TO BE INSTALLED $cnt = 0 Foreach ($Result in $Installer.Updates) { Switch ($InstallationResult.GetUpdateResult($cnt).ResultCode) { 0 {Write-Host "$($Result.Title): Not Started" ; break} 1 {Write-Host "$($Result.Title): In Progress" ; break} 2 {Write-Host "$($Result.Title): Succeeded" ; break} 3 {Write-Host "$($Result.Title): Succeeded with errors" ; break} 4 {Write-Host "$($Result.Title): Failed" ; break} 5 {Write-Host "$($Result.Title): Process stopped before completing" ; break} } $cnt++ } # RETURNS TO MAIN MENU AFTER A PAUSE SO RESULTS CAN BE EASILY VIEWED Write-Host -ForegroundColor Yellow "Returning to main menu..." Start-Sleep -Seconds 3 sc_Create-MainMenu } ################################################################ LOGOFF ################################################################ function sc_Logoff ( ) { logoff } ################################################################ RESTART ############################################################### function sc_Restart ( ) { Restart-Computer -Force } ############################################################### SHUTDOWN ############################################################### function sc_Shutdown ( ) { Stop-Computer -Force } ################################################################# EXIT ################################################################# function sc_Exit ( ) { CMD } ########################################################### MAIN SCRIPT BODY ########################################################### # SETS WINDOW AND BUFFER SIZE $Width = 95 $Buffer = New-Object -TypeName System.Management.Automation.Host.Size ($Width,3000) $Window = New-Object -TypeName System.Management.Automation.Host.Size ($Width,($Host.UI.RawUI.MaxWindowSize.Height * .7)) $Host.UI.RawUI.WindowSize = $Window $Host.UI.RawUI.BufferSize = $Buffer # INITIATES CORE FUNCTION sc_Create-MainMenu |