├── SilentInstallation_Samples ├── .gitkeep ├── LICENSE └── readme.md ├── WindowsUpdates_Sample ├── MSU │ └── Put_your_MSU_updates_here ├── SSU │ └── Put_your_SSU_updates_here ├── .NET │ └── Put_your_DOTNET_updates_here ├── LICENSE ├── readme.md └── InstallWindowsUpdates.ps1 ├── DeviceLockdown_Sample ├── img │ ├── Unbranded.png │ ├── Before_Unbranded.png │ ├── CustomLogon_HideAutoLogonUI_on.png │ ├── CustomLogon_HideAutoLogonUI_off.png │ ├── CustomLogon_withBrandingNeutral.png │ └── CustomLogon_withoutBrandingNeutral.png ├── LICENSE ├── Reset_All_DeviceLockdownFeatures.ps1 ├── README.md └── Configure_DeviceLockdown.ps1 ├── ConfigureBasicSystem_Sample ├── Windows │ ├── Configure_Firewall.ps1 │ ├── Disable_Autologin.ps1 │ ├── Enable_Autologin.ps1 │ ├── Change_Administrator_Password.ps1 │ ├── Create_New_User.ps1 │ ├── LICENSE │ ├── Create_New_Administrator.ps1 │ ├── Enable_RDP.ps1 │ ├── Disable_RDP.ps1 │ ├── Open_Firewall_Port.ps1 │ └── README.md ├── TwinCAT │ ├── Install_TC_RTE_Driver.ps1 │ ├── Activate_TC_Auto_Run.ps1 │ ├── Activate_Core_Isolation.ps1 │ ├── LICENSE │ ├── Change_AMS_Net_id.ps1 │ ├── Add_ADS_Route.ps1 │ └── README.md ├── README.md └── LICENSE ├── Bitlocker_Samples ├── LICENSE ├── README.md └── Enable_Bitlocker.ps1 ├── GetIPCSystemInformation_Sample ├── LICENSE ├── GetIPCSystemInformation.ps1 └── README.md └── README.md /SilentInstallation_Samples/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /WindowsUpdates_Sample/MSU/Put_your_MSU_updates_here: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /WindowsUpdates_Sample/SSU/Put_your_SSU_updates_here: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /WindowsUpdates_Sample/.NET/Put_your_DOTNET_updates_here: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /DeviceLockdown_Sample/img/Unbranded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Beckhoff/windows-tools/HEAD/DeviceLockdown_Sample/img/Unbranded.png -------------------------------------------------------------------------------- /DeviceLockdown_Sample/img/Before_Unbranded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Beckhoff/windows-tools/HEAD/DeviceLockdown_Sample/img/Before_Unbranded.png -------------------------------------------------------------------------------- /ConfigureBasicSystem_Sample/Windows/Configure_Firewall.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Beckhoff/windows-tools/HEAD/ConfigureBasicSystem_Sample/Windows/Configure_Firewall.ps1 -------------------------------------------------------------------------------- /DeviceLockdown_Sample/img/CustomLogon_HideAutoLogonUI_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Beckhoff/windows-tools/HEAD/DeviceLockdown_Sample/img/CustomLogon_HideAutoLogonUI_on.png -------------------------------------------------------------------------------- /DeviceLockdown_Sample/img/CustomLogon_HideAutoLogonUI_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Beckhoff/windows-tools/HEAD/DeviceLockdown_Sample/img/CustomLogon_HideAutoLogonUI_off.png -------------------------------------------------------------------------------- /DeviceLockdown_Sample/img/CustomLogon_withBrandingNeutral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Beckhoff/windows-tools/HEAD/DeviceLockdown_Sample/img/CustomLogon_withBrandingNeutral.png -------------------------------------------------------------------------------- /DeviceLockdown_Sample/img/CustomLogon_withoutBrandingNeutral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Beckhoff/windows-tools/HEAD/DeviceLockdown_Sample/img/CustomLogon_withoutBrandingNeutral.png -------------------------------------------------------------------------------- /ConfigureBasicSystem_Sample/Windows/Disable_Autologin.ps1: -------------------------------------------------------------------------------- 1 | ################################### 2 | ## Disable Autologin Administrator 3 | ################################### 4 | 5 | $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" 6 | 7 | Set-ItemProperty $RegPath "AutoAdminLogon" -Value "0" -type String 8 | 9 | ############################ 10 | -------------------------------------------------------------------------------- /ConfigureBasicSystem_Sample/TwinCAT/Install_TC_RTE_Driver.ps1: -------------------------------------------------------------------------------- 1 | ############################ 2 | ## Install RTE Driver 3 | ############################ 4 | 5 | $adapter_name = "Ethernet" 6 | 7 | # Install driver for adapter 8 | Start-Process -Wait C:\TwinCAT\3.1\System\TcRteInstall.exe -ArgumentList "-installnic $adapter_name /S" -PassThru 9 | 10 | ############################ -------------------------------------------------------------------------------- /ConfigureBasicSystem_Sample/TwinCAT/Activate_TC_Auto_Run.ps1: -------------------------------------------------------------------------------- 1 | ##################################### 2 | ## Activate TwinCAT Run Mode on Boot 3 | ##################################### 4 | 5 | # Check os architecture 6 | if ([System.Environment]::Is64BitProcess) { 7 | $RegPath = "HKLM:\SOFTWARE\WOW6432Node\Beckhoff\TwinCAT3\System" 8 | } 9 | else { 10 | $RegPath = "HKLM:\SOFTWARE\Beckhoff\TwinCAT3\System" 11 | } 12 | 13 | # Set reg key 14 | Set-ItemProperty $RegPath "SysStartupState" -Value 5 -type DWord -PassThru 15 | 16 | ############################ -------------------------------------------------------------------------------- /ConfigureBasicSystem_Sample/Windows/Enable_Autologin.ps1: -------------------------------------------------------------------------------- 1 | ################################## 2 | ## Enable Autologin Administrator 3 | ################################## 4 | 5 | $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" 6 | $DefaultUsername = "SystemAdministrator" 7 | $DefaultPassword = "adminpw" 8 | 9 | Set-ItemProperty $RegPath "AutoAdminLogon" -Value "1" -type String 10 | Set-ItemProperty $RegPath "DefaultUsername" -Value "$DefaultUsername" -type String 11 | Set-ItemProperty $RegPath "DefaultPassword" -Value "$DefaultPassword" -type String 12 | 13 | 14 | ############################ 15 | -------------------------------------------------------------------------------- /ConfigureBasicSystem_Sample/README.md: -------------------------------------------------------------------------------- 1 | # ConfigureBasicSystem 2 | 3 | There are some basic settings that are useful to get started with a Beckhoff Windows System quickly. We provide sample scripts for the following settings: 4 | 5 | ### Windows 6 | 7 | • Create administrator and user accounts 8 | • Set administrator and user password 9 | • Enable or disable auto login 10 | • Configure Firewall (turn on, disable rules, block traffic) 11 | • Enable or disable RDP 12 | • Open Firewall ports 13 | 14 | ### TwinCAT 15 | 16 | • Start TwinCAT in Run mode on boot 17 | • Isolate core for TwinCAT 18 | • Add ADS Route 19 | • Change AMS Net Id 20 | • Install EtherCAT Driver with TwinCAT RTE Install 21 | -------------------------------------------------------------------------------- /ConfigureBasicSystem_Sample/Windows/Change_Administrator_Password.ps1: -------------------------------------------------------------------------------- 1 | ########################## 2 | ## Change User Password 3 | ########################## 4 | 5 | $username = "Administrator" 6 | $password = "TwinCAT123" 7 | $passwordSec = ConvertTo-SecureString -String $password -AsPlainText -Force 8 | 9 | # Create new user account if it does not exist 10 | $account = Get-LocalUser -Name $username -ErrorAction SilentlyContinue 11 | 12 | # Change Password if User Exists 13 | if (-not ($null -eq $account)) { 14 | $account = Get-LocalUser -Name $username 15 | $account | Set-LocalUser -Password $passwordSec 16 | } 17 | else { 18 | Write-Host "User named $username does not exist" 19 | } 20 | 21 | ################################### -------------------------------------------------------------------------------- /ConfigureBasicSystem_Sample/TwinCAT/Activate_Core_Isolation.ps1: -------------------------------------------------------------------------------- 1 | ############################ 2 | ## Isolate Cores 3 | ############################ 4 | 5 | # This script isolates one CPU core 6 | $logicalProcessors = (Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors 7 | $logicalProcessorsNew = $logicalProcessors - 1 8 | Start-Process -Wait -WindowStyle Hidden -FilePath "bcdedit" -ArgumentList "/set numproc $logicalProcessorsNew" 9 | 10 | Write-Host "Script execution finished. Changed from $logicalProcessors core to $logicalProcessorsNew shared core and 1 isolated core." 11 | Write-Host "Press ENTER to continue and restart the system. Otherwise just clone this window." 12 | Read-Host 13 | Restart-Computer 14 | 15 | ############################ -------------------------------------------------------------------------------- /Bitlocker_Samples/LICENSE: -------------------------------------------------------------------------------- 1 | BSD Zero Clause License 2 | 3 | Copyright (C) 2022 by Beckhoff Automation GmbH & Co. KG 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------------- /DeviceLockdown_Sample/LICENSE: -------------------------------------------------------------------------------- 1 | BSD Zero Clause License 2 | 3 | Copyright (C) 2022 by Beckhoff Automation GmbH & Co. KG 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------------- /WindowsUpdates_Sample/LICENSE: -------------------------------------------------------------------------------- 1 | BSD Zero Clause License 2 | 3 | Copyright (C) 2024 by Beckhoff Automation GmbH & Co. KG 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------------- /SilentInstallation_Samples/LICENSE: -------------------------------------------------------------------------------- 1 | BSD Zero Clause License 2 | 3 | Copyright (C) 2022 by Beckhoff Automation GmbH & Co. KG 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------------- /ConfigureBasicSystem_Sample/LICENSE: -------------------------------------------------------------------------------- 1 | BSD Zero Clause License 2 | 3 | Copyright (C) 2022 by Beckhoff Automation GmbH & Co. KG 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------------- /GetIPCSystemInformation_Sample/LICENSE: -------------------------------------------------------------------------------- 1 | BSD Zero Clause License 2 | 3 | Copyright (C) 2022 by Beckhoff Automation GmbH & Co. KG 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------------- /ConfigureBasicSystem_Sample/TwinCAT/LICENSE: -------------------------------------------------------------------------------- 1 | BSD Zero Clause License 2 | 3 | Copyright (C) 2022 by Beckhoff Automation GmbH & Co. KG 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------------- /ConfigureBasicSystem_Sample/Windows/Create_New_User.ps1: -------------------------------------------------------------------------------- 1 | ########################## 2 | ## Add a new user 3 | ########################## 4 | 5 | # Create a new user 6 | $username = "TwinCAT_User" 7 | $password = "userpw" 8 | $passwordSec = ConvertTo-SecureString -String $password -AsPlainText -Force 9 | 10 | # Create new user account if it does not exist 11 | $account = Get-LocalUser -Name $username -ErrorAction SilentlyContinue 12 | if (-not ($null -eq $account)) { 13 | Remove-LocalUser -Name $username 14 | } 15 | New-LocalUser -Name $username -FullName $username -Description "Standard Windows user" -Password $passwordSec 16 | 17 | # Make the user part of the User Group 18 | Add-LocalGroupMember -Group "Users" -Member $username 19 | 20 | ########################## 21 | -------------------------------------------------------------------------------- /ConfigureBasicSystem_Sample/Windows/LICENSE: -------------------------------------------------------------------------------- 1 | BSD Zero Clause License 2 | 3 | Copyright (C) 2022 by Beckhoff Automation GmbH & Co. KG 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------------- /ConfigureBasicSystem_Sample/Windows/Create_New_Administrator.ps1: -------------------------------------------------------------------------------- 1 | ############################# 2 | ## Add a new Administrator 3 | ############################# 4 | 5 | # Create a new Administrator 6 | $username = "SystemAdministrator" 7 | $password = "adminpw" 8 | $passwordSec = ConvertTo-SecureString -String $password -AsPlainText -Force 9 | 10 | # Create new user account if it does not exist 11 | $account = Get-LocalUser -Name $username -ErrorAction SilentlyContinue 12 | if (-not ($null -eq $account)) { 13 | Remove-LocalUser -Name $username 14 | } 15 | New-LocalUser -Name $username -FullName $username -Description "System Administrator" -Password $passwordSec 16 | 17 | # Make the user part of the Administrators Group 18 | Add-LocalGroupMember -Group "Administrators" -Member $username 19 | 20 | ########################## -------------------------------------------------------------------------------- /ConfigureBasicSystem_Sample/Windows/Enable_RDP.ps1: -------------------------------------------------------------------------------- 1 | ############################ 2 | ## Enable Remote Desktop 3 | ############################ 4 | 5 | # Enable RDP in Registry 6 | Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -name "fDenyTSConnections" -value 0 7 | 8 | # Allow RDP TCP-In (port 3389) 9 | if($(Get-NetFirewallRule -DisplayName 'Remote Desktop - User Mode (TCP-In)')) 10 | { 11 | Set-NetFirewallRule -DisplayName 'Remote Desktop - User Mode (TCP-In)' -Enabled True 12 | } 13 | else 14 | { 15 | New-NetFirewallRule -DisplayName 'Remote Desktop - User Mode (TCP-In)' ` 16 | -Profile Any ` 17 | -Direction Inbound ` 18 | -Action Allow ` 19 | -Protocol TCP ` 20 | -LocalPort 3389 21 | } 22 | 23 | ############################# 24 | -------------------------------------------------------------------------------- /ConfigureBasicSystem_Sample/Windows/Disable_RDP.ps1: -------------------------------------------------------------------------------- 1 | ############################ 2 | ## Disable Remote Desktop 3 | ############################ 4 | 5 | # Disable RDP in Registry 6 | Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -name "fDenyTSConnections" -value 1 7 | 8 | # Block RDP TCP-In (port 3389) 9 | if($(Get-NetFirewallRule -DisplayName 'Remote Desktop - User Mode (TCP-In)')) 10 | { 11 | Set-NetFirewallRule -DisplayName 'Remote Desktop - User Mode (TCP-In)' -Enabled False 12 | } 13 | else 14 | { 15 | New-NetFirewallRule -DisplayName 'Remote Desktop - User Mode (TCP-In)' ` 16 | -Profile Any ` 17 | -Direction Inbound ` 18 | -Action Block ` 19 | -Protocol TCP ` 20 | -LocalPort 3389 21 | } 22 | 23 | ############################# 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Various Tools for Windows Images made by Beckhoff 2 | 3 | This repository provides a collection of tools/scripts and whitepapers 4 | for Windows Images made by Beckhoff. 5 | 6 | ## Content 7 | 8 | * **[Bitlocker_Samples](Bitlocker_Samples/README.md)** 9 | 10 | These examples can be used to configure or modify the bitlocker settings e.g. turn on / off 11 | 12 | * **[ConfigureBasicSystem_Sample](ConfigureBasicSystem_Sample/README.md)** 13 | 14 | This is an example to do basic configurations in a Beckhoff Windows image (general system and TwinCAT) 15 | 16 | * **[DeviceLockdown_Sample](DeviceLockdown_Sample/README.md)** 17 | 18 | This example can be used to configure or modify the Device Lockdwon Features of Windows IoT Enterprise 19 | 20 | * **[GetIPCSystemInformation_Sample](GetIPCSystemInformation_Sample/README.md)** 21 | 22 | This is an example to get some helpful system information about your Beckhoff Windows images 23 | 24 | * **[SilentInstallation_Samples](SilentInstallation_Samples/readme.md)** 25 | 26 | These examples show the silent parameters for TwinCAT 3.1 Build 4024 and its TwinCAT Functions 27 | 28 | * **[WindowsUpdates_Samples](WindowsUpdates_Sample/readme.md)** 29 | 30 | These examples can be used to install Windows security updates -------------------------------------------------------------------------------- /ConfigureBasicSystem_Sample/Windows/Open_Firewall_Port.ps1: -------------------------------------------------------------------------------- 1 | ############################ 2 | ## Open Firewall Ports 3 | ############################ 4 | 5 | # Allow ADS (TCP) (port 48898) 6 | New-NetFirewallRule -DisplayName 'TwinCAT ADS (TCP)' ` 7 | -Profile @('Domain', 'Private') ` 8 | -Direction Inbound ` 9 | -Action Allow ` 10 | -Protocol TCP ` 11 | -LocalPort 48898 12 | 13 | New-NetFirewallRule -DisplayName 'TwinCAT ADS (TCP)' ` 14 | -Profile @('Domain', 'Private') ` 15 | -Direction Outbound ` 16 | -Action Allow ` 17 | -Protocol TCP ` 18 | -LocalPort 48898 19 | 20 | # Allow ADS (TCP) (port 48899) 21 | New-NetFirewallRule -DisplayName 'TwinCAT ADS (UDP)' ` 22 | -Profile @('Domain', 'Private') ` 23 | -Direction Inbound ` 24 | -Action Allow ` 25 | -Protocol UDP ` 26 | -LocalPort 48899 27 | 28 | New-NetFirewallRule -DisplayName 'TwinCAT ADS (UDP)' ` 29 | -Profile @('Domain', 'Private') ` 30 | -Direction Outbound ` 31 | -Action Allow ` 32 | -Protocol UDP ` 33 | -LocalPort 48899 34 | 35 | ################################### -------------------------------------------------------------------------------- /GetIPCSystemInformation_Sample/GetIPCSystemInformation.ps1: -------------------------------------------------------------------------------- 1 | # General Baseboard Information 2 | Write-Host "General Baseboard Information" 3 | Get-WmiObject Win32_BaseBoard | Format-List * 4 | 5 | 6 | # Installed Windows Updates 7 | Write-Host "Installed Windows Updates" 8 | Get-WmiObject Win32_QuickFixEngineering | Select-Object HotFixID, Description, InstalledOn 9 | 10 | 11 | # OS Build 12 | Write-Host "OS Build" 13 | (Get-WmiObject Win32_OperatingSystem).BuildNumber 14 | 15 | 16 | # Beckhoff Image Number 17 | Write-Host "Beckhoff Image Number" 18 | Get-ItemPropertyValue 'HKLM:\SOFTWARE\Beckhoff\IPC' 'Image' 19 | 20 | 21 | # Beckhoff Image Version 22 | Write-Host "Beckhoff Image Version" 23 | Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Beckhoff\IPC' 'Version' 24 | 25 | 26 | 27 | # EditionId 28 | Write-Host "EditionId" 29 | Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Beckhoff\IPC' 'EditionId' 30 | 31 | 32 | # Driver Package 33 | Write-Host "Driver Package" 34 | Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Beckhoff\IPC' 'DriverPackage' 35 | 36 | 37 | # Get Baseboard 38 | Write-Host "Baseboard" 39 | Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Beckhoff\IPC' 'Platform' 40 | 41 | 42 | # Get Computer Name 43 | Write-Host "Computer Name" 44 | Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Beckhoff\IPC' 'LastComputerName' 45 | 46 | 47 | # Get MAC Address 48 | Write-Host "MAC Address" 49 | Get-WmiObject win32_networkadapterconfiguration | select description, macaddress 50 | 51 | 52 | # Get Update Build Revision 53 | Write-Host "Update Build Revision" 54 | Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' 'UBR' 55 | 56 | -------------------------------------------------------------------------------- /ConfigureBasicSystem_Sample/TwinCAT/Change_AMS_Net_id.ps1: -------------------------------------------------------------------------------- 1 | ############################ 2 | ## Change AMS Net ID 3 | ############################ 4 | 5 | #IP Address (Used to change the AMS Net ID) 6 | $ipAddr = "192.168.1.5" 7 | 8 | # Check os architecture 9 | if ([System.Environment]::Is64BitProcess) { 10 | $regKeyWow6432 = "HKLM:\SOFTWARE\WOW6432Node\" 11 | } 12 | else { 13 | $regKeyWow6432 = "HKLM:\SOFTWARE\" 14 | } 15 | 16 | # Create registry path 17 | $regKeyBeckhoff = $regKeyWow6432 + "Beckhoff\" 18 | $regKeyTc = $regKeyBeckhoff + "TwinCAT3\" 19 | $regKeyTcSystem = $regKeyTc + "System" 20 | $regKeyPropertyAmsNetId = "AmsNetId" 21 | 22 | # Check if Beckhoff RegKey exists (does not exist on systems without TwinCAT) 23 | if (Test-Path $regKeyTcSystem) { 24 | # Reading current AmsNetId from Windows Registry 25 | $amsNetId = Get-ItemProperty -Path $regKeyTcSystem -Name $regKeyPropertyAmsNetId 26 | 27 | # Using the IP address 28 | $ipAddrArr = $ipAddr.Split(".") 29 | 30 | # Stopping TwinCAT System Service and all dependencies 31 | Stop-Service -Name "TcSysSrv" -Force 32 | 33 | # Setting new AMS Net ID based on local IP address, the last two bytes from old AMS Net ID are kept 34 | $amsNetId.AmsNetId[0] = $ipAddrArr[0] 35 | $amsNetId.AmsNetId[1] = $ipAddrArr[1] 36 | $amsNetId.AmsNetId[2] = $ipAddrArr[2] 37 | $amsNetId.AmsNetId[3] = $ipAddrArr[3] 38 | Set-ItemProperty -Path $regKeyTcSystem -Name $regKeyPropertyAmsNetId -Value $amsNetId.AmsNetId 39 | 40 | # Starting TwinCAT System Service 41 | Start-Service -Name "TcSysSrv" 42 | 43 | # Retsart system 44 | Write-Host "Press ENTER to continue and restart the system. Otherwise just clone this window." 45 | Read-Host 46 | Restart-Computer 47 | 48 | } 49 | 50 | ############################ -------------------------------------------------------------------------------- /ConfigureBasicSystem_Sample/TwinCAT/Add_ADS_Route.ps1: -------------------------------------------------------------------------------- 1 | ##################################### 2 | ## Add New ADS Route 3 | ##################################### 4 | 5 | # Location of routes file 6 | $routesPath = "C:\TwinCAT\3.1\Target" 7 | $routesFile = "StaticRoutes.xml" 8 | 9 | # Create a new Route Element 10 | $xmlfile = [xml](Get-Content "$routesPath\$routesFile") 11 | $new_route_node =$xmlfile.SelectSingleNode("//TcConfig/RemoteConnections") 12 | 13 | $new_route_node.AppendChild($xmlfile.CreateElement("Route"))|out-null 14 | $new_route_node = $xmlfile.SelectSingleNode("//TcConfig/RemoteConnections/Route") 15 | 16 | # Add a new name "RemoteSystem123" for the route 17 | $new_name_node = $new_route_node.AppendChild($xmlfile.CreateElement("Name")) 18 | $new_name_node.AppendChild($xmlfile.CreateTextNode("RemoteSystem123")) | Out-Null 19 | 20 | # Add IP address "192.168.1.75" for the route 21 | $new_address_node = $new_route_node.AppendChild($xmlfile.CreateElement("Address")) 22 | $new_address_node.AppendChild($xmlfile.CreateTextNode("192.168.1.75")) | Out-Null 23 | 24 | # Add NetId "192.168.1.75.1.1" for the route 25 | $new_netid_node = $new_route_node.AppendChild($xmlfile.CreateElement("NetId")) 26 | $new_netid_node.AppendChild($xmlfile.CreateTextNode("192.168.1.75.1.1")) | Out-Null 27 | 28 | # Add a route type 29 | $new_type_node = $new_route_node.AppendChild($xmlfile.CreateElement("Type")) 30 | $new_type_node.AppendChild($xmlfile.CreateTextNode("TCP_IP")) | Out-Null 31 | 32 | # Add route flags 33 | $new_flags_node = $new_route_node.AppendChild($xmlfile.CreateElement("Flags")) 34 | $new_flags_node.AppendChild($xmlfile.CreateTextNode("64")) | Out-Null 35 | 36 | # Save the new route 37 | $xmlfile.save("$routesPath\$routesFile") 38 | 39 | ######################################### -------------------------------------------------------------------------------- /Bitlocker_Samples/README.md: -------------------------------------------------------------------------------- 1 | # Bitlocker Configuration 2 | 3 | To use Bitlocker some mandatory settings must be respected: 4 | - Operating system is Windows 10 with 64 Bit architecture 5 | - Bitlocker is supported starting with Windows 10 IoT Enterprise 2019 LTSC 6 | - fTPM is enabled in the BIOS 7 | - BIOS Boot mode is UEFI 8 | 9 | The sample checks the following settings: 10 | - TwinCAT state is in CONFIG mode 11 | - TwinCAT powershell module AdsApi is available 12 | - Boot mode is UEFI or LEGACY 13 | - OS architecture is 32 Bit or 64 Bit 14 | - OS release id is supported (below 1809 is not supported) 15 | - fTPM or FTPM is present 16 | - fTPM or FTPM is ready 17 | - Recovery partitions exist 18 | - Bitlocker status state 19 | _FullyDecrypted_ 20 | The script goes on 21 | _EncryptionInProgress_ 22 | The script stops here because the encryption is in progress 23 | _DecryptionInProgress_ 24 | The script stops here because the decryption is in progress 25 | _FullyEncrypted_ 26 | The script stops here because the volume is already encrypted 27 | - Add Bitlocker Protectors: TpmProtector, RecoveryPasswordProtector 28 | - Initialize TPM, add recovery partition if needed and enable Bitlocker 29 | - Save Bitlocker KeyProtectors to defined target location $KeyProtectorLocation 30 | In the sample it is "C:\Users\Administrator\Desktop\KeyProtector.txt" 31 | 32 | 33 | Error Code Description: 34 | - _$Error_Success_ = 0 35 | The script runs successfully 36 | - _$Error_OsLegacy_ = 10 37 | OS is LEGACY which is not supported 38 | - _$Error_Os32Bit_ = 11 39 | OS is 32Bit which is not supported 40 | - _$Error_OsReleaseId_ = 12 41 | OS ReleaseID is lower than 1809 which is not supported 42 | - _$Error_TpmNotPreent_ = 20 43 | TPM is not present 44 | - _$Error_TpmNotReady_ = 21 45 | TPM is not ready 46 | - _$Error_BLDriveNotReady_ = 30 47 | Bitlocker mountpoint does not exist 48 | - _$Error_BLEncryptionInProgress_ = 31 49 | Bitlocker Encryption is in progress 50 | - _$Error_BLDecryptionInProgress_ = 32 51 | Bitlocker Decryption is in progress 52 | - _$Error_BLFullyEncrypted_ = 32 53 | Bitlocker is already encrypted 54 | - _$Error_TcSysPsExtensionMissing_ = 40 55 | TwinCAT powershell module AdsApi is missing 56 | - _$Error_TcSysStateRunning_ = 41 57 | TwinCAT state is running 58 | -------------------------------------------------------------------------------- /WindowsUpdates_Sample/readme.md: -------------------------------------------------------------------------------- 1 | # Windows Security Update Installation Sample 2 | 3 | **Disclaimer**\ 4 | Beckhoff is not responsible for any side effects negatively affecting the real-time capabilities of your TwinCAT control application possibly caused by updates. A backup should be created every time before installing an update. As the installation process of Windows updates requires free disk space, Beckhoff recommends to free at least 10 GB in advance. Only administrators or IT experts should perform the backup and update procedure. 5 | 6 | 7 | This script is intended for offline installation with Windows security updates.\ 8 | The following points are taken into account: 9 | 10 | **UWF (Unified Write Filter) filter status**\ 11 | Checks whether the Unified Write Filter is enabled or disabled. It ensures that the script doesn't interfere with systems where UWF is active. 12 | 13 | **Volume free space**\ 14 | The amount of free space (10 GB) available on the system drive will be checked. It ensures that there's adequate space for performing updates or other operations without causing issues due to insufficient disk space. 15 | 16 | **Windows Update Service**\ 17 | This checks the status of the Windows Update service, ensuring that it's running. This service is crucial for downloading and installing Windows updates, so ensuring its status is part of maintaining the system's update functionality. 18 | 19 | **Directory existence at C:\WinUpdate \ [SSU] \ [MSU] \ [.NET]**\ 20 | Verifies the presence of specific directories on the system drive where Windows update files are typically stored. It ensures that the necessary directories for storing update files are present, likely for future update operations. 21 | 22 | **Windows Updates properly installed**\ 23 | This checks whether Windows updates have been successfully installed on the system. Ensuring that updates are properly installed helps maintain system security and stability by keeping the operating system up-to-date with the latest patches and fixes. 24 | 25 | **Removal of properly installed Windows Updates installation files at C:\WinUpdate \ [SSU] \ [MSU] \ [.NET]**\ 26 | This part of the script likely cleans up the directories mentioned earlier by removing update installation files that are no longer needed after updates have been successfully installed. This helps free up disk space and keeps the system tidy. 27 | 28 | 29 | Security Updates for Windows 10 IoT Enterprise 2021 LTSC and 2019 LTSC already contain the SSU files (SSU=Servicing Stack Update).\ 30 | For Windows 10 IoT Enterprise 2016 LTSB the SSU files comes as separate installation and needs to be installed in front. 31 | 32 | Example:\ 33 | **Windows 10 IoT Enterprise 2021 LTSC (KB5035845)** 34 | ``` 35 | windows10.0-kb5035845-x64_b4c28c9c57c35bac9226cde51685e41c281e40eb.msu 36 | 37 | Already contains the SSU file 38 | .\windows10.0-kb5035845-x64_b4c28c9c57c35bac9226cde51685e41c281e40eb.msu: Windows10.0-KB5035845-x64.cab 39 | .\windows10.0-kb5035845-x64_b4c28c9c57c35bac9226cde51685e41c281e40eb.msu: WSUSSCAN.cab 40 | .\windows10.0-kb5035845-x64_b4c28c9c57c35bac9226cde51685e41c281e40eb.msu: Windows10.0-KB5035845-x64-pkgProperties.txt 41 | .\windows10.0-kb5035845-x64_b4c28c9c57c35bac9226cde51685e41c281e40eb.msu: Windows10.0-KB5035845-x64_uup.xml 42 | .\windows10.0-kb5035845-x64_b4c28c9c57c35bac9226cde51685e41c281e40eb.msu: SSU-19041.4163-x64.cab 43 | ``` 44 | 45 | 46 | -------------------------------------------------------------------------------- /GetIPCSystemInformation_Sample/README.md: -------------------------------------------------------------------------------- 1 | # GetIPCSystemInformation 2 | Running the following commands will help you to gather system information using WMI and Registry query. 3 | The Sample script contains all commands explained in this file. 4 | 5 | ## Using WMI 6 | Running the following commands will help you to gather system information using WMI. 7 | 8 | #### 1. General Baseboard Information: 9 | 10 | ``` 11 | Get-WmiObject Win32_BaseBoard | Format-List * 12 | ``` 13 | 14 | Output is for example: 15 | ``` 16 | Product: CB7476 17 | Version: G2 18 | ``` 19 | 20 | #### 2. Installed Windows Updates: 21 | 22 | You can get a brief overview of the installed updates in the command line via the following command: 23 | 24 | ``` 25 | Get-WmiObject Win32_QuickFixEngineering | Select-Object HotFixID, Description, InstalledOn 26 | ``` 27 | 28 | to get a complete overview of all updates and their information (e.g. description, caption, etc.). 29 | 30 | #### 3. OS Build: 31 | 32 | ``` 33 | (Get-WmiObject Win32_OperatingSystem).BuildNumber 34 | ``` 35 | 36 | Output is: 37 | ``` 38 | 26100 39 | ``` 40 | 41 | ## 2.2. Using Registry 42 | 43 | With the help of PowerShell, information about the image can be read out easily. For example, all keys and values under a registry key can be read out as follows: 44 | ``` 45 | Get-ItemProperty [-Path] [-Name] 46 | ``` 47 | And the value of a specific key as follows: 48 | ``` 49 | Get-ItemPropertyValue [-Path] [-Name] 50 | ``` 51 | 52 | Image and device information in Beckhoff Images can be found at: 53 | ``` 54 | HKLM\SOFTWARE\Beckhoff\IPC 55 | ``` 56 | 57 | #### 1. Image Version: 58 | **Get image:** 59 | ``` 60 | Get-ItemPropertyValue 'HKLM:\SOFTWARE\Beckhoff\IPC' 'Image' 61 | ``` 62 | 63 | Output is for example: 64 | ``` 65 | IN-1211-0712-11-1 66 | ``` 67 | 68 | **Get version:** 69 | ``` 70 | Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Beckhoff\IPC' 'Version' 71 | ``` 72 | 73 | Output is for example: 74 | ``` 75 | 2025-12-00051 76 | ``` 77 | 78 | **Get edition:** 79 | ``` 80 | Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Beckhoff\IPC' 'EditionId' 81 | ``` 82 | 83 | Output is for example: 84 | ``` 85 | 2024 LTSC 86 | ``` 87 | #### 2. Driver Package 88 | **Get driver package:** 89 | 90 | ``` 91 | Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Beckhoff\IPC' 'DriverPackage' 92 | ``` 93 | 94 | Output is for example: 95 | ``` 96 | 8.11.6.0 97 | ``` 98 | 99 | #### 3. Baseboard: 100 | **Get baseboard:** 101 | ``` 102 | Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Beckhoff\IPC' 'Platform' 103 | ``` 104 | 105 | Output is for example: 106 | ``` 107 | CB7476 108 | ``` 109 | 110 | #### 4. Device information: 111 | **Get computer name:** 112 | ``` 113 | Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Beckhoff\IPC' 'LastComputerName' 114 | ``` 115 | 116 | Output is for example: 117 | ``` 118 | CP-XXXXXX 119 | ``` 120 | 121 | **Get MAC:** 122 | ``` 123 | Get-WmiObject win32_networkadapterconfiguration | select description, macaddress 124 | ``` 125 | 126 | Output is for example: 127 | ``` 128 | Intel(R) Ethernet Controller I226-IT 00:01:05:XX:XX:XX 129 | ``` 130 | 131 | #### 5. OS Update Build Revision 132 | **Get Update Build Revision:** 133 | ``` 134 | Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' 'UBR' 135 | ``` 136 | 137 | Output is for example: 138 | ``` 139 | 4351 140 | ``` 141 | -------------------------------------------------------------------------------- /ConfigureBasicSystem_Sample/TwinCAT/README.md: -------------------------------------------------------------------------------- 1 | # ConfigureBasicSystem 2 | 3 | There are some basic settings that are useful to get started with a Beckhoff Windows System quickly. We provide sample scripts for the following settings: 4 | 5 | ## TwinCAT 6 | 7 | • Start TwinCAT in Run mode on boot 8 | • Activate core isolation 9 | • Add ADS Route 10 | • Change AMS Net Id 11 | • Install EtherCAT Driver with TwinCAT RTE Install 12 | 13 | ## TwinCAT configuration 14 | 15 | Start TwinCAT in Run mode on boot: 16 | ``` 17 | # Check os architecture 18 | if ([System.Environment]::Is64BitProcess) { 19 | $RegPath = "HKLM:\SOFTWARE\WOW6432Node\Beckhoff\TwinCAT3\System" 20 | } 21 | else { 22 | $RegPath = "HKLM:\SOFTWARE\Beckhoff\TwinCAT3\System" 23 | } 24 | 25 | # Set reg key 26 | Set-ItemProperty $RegPath "SysStartupState" -Value 5 -type DWord -PassThru 27 | ``` 28 | 29 | Activate core isolation: 30 | ``` 31 | $logicalProcessors = (Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors 32 | $logicalProcessorsNew = $logicalProcessors - 1 33 | Start-Process -Wait -WindowStyle Hidden -FilePath "bcdedit" -ArgumentList "/set numproc $logicalProcessorsNew" 34 | ``` 35 | Add ADS Route: 36 | ``` 37 | # Location of routes file 38 | $routesPath = "C:\TwinCAT\3.1\Target" 39 | $routesFile = "StaticRoutes.xml" 40 | 41 | # Create a new Route Element 42 | $xmlfile = [xml](Get-Content "$routesPath\$routesFile") 43 | $new_route_node =$xmlfile.SelectSingleNode("//TcConfig/RemoteConnections") 44 | 45 | $new_route_node.AppendChild($xmlfile.CreateElement("Route"))|out-null 46 | $new_route_node = $xmlfile.SelectSingleNode("//TcConfig/RemoteConnections/Route") 47 | 48 | # Add a new name "RemoteSystem123" for the route 49 | $new_name_node = $new_route_node.AppendChild($xmlfile.CreateElement("Name")) 50 | $new_name_node.AppendChild($xmlfile.CreateTextNode("RemoteSystem123")) | Out-Null 51 | 52 | # Add address "192.168.1.75" for the route 53 | $new_address_node = $new_route_node.AppendChild($xmlfile.CreateElement("Address")) 54 | $new_address_node.AppendChild($xmlfile.CreateTextNode("192.168.1.75")) | Out-Null 55 | 56 | # Add NetId "192.168.1.75.1.1" for the route 57 | $new_netid_node = $new_route_node.AppendChild($xmlfile.CreateElement("NetId")) 58 | $new_netid_node.AppendChild($xmlfile.CreateTextNode("192.168.1.75.1.1")) | Out-Null 59 | 60 | # Add a route type 61 | $new_type_node = $new_route_node.AppendChild($xmlfile.CreateElement("Type")) 62 | $new_type_node.AppendChild($xmlfile.CreateTextNode("TCP_IP")) | Out-Null 63 | 64 | # Add route flags 65 | $new_flags_node = $new_route_node.AppendChild($xmlfile.CreateElement("Flags")) 66 | $new_flags_node.AppendChild($xmlfile.CreateTextNode("64")) | Out-Null 67 | 68 | # Save the new route 69 | $xmlfile.save("$routesPath\$routesFile") 70 | ``` 71 | Change AMS Net Id: 72 | ``` 73 | #IP Address (Used to change the AMS Net ID) 74 | $ipAddr = "192.168.1.5" 75 | 76 | $regKeyWow6432 = "HKLM:\SOFTWARE\WOW6432Node\" 77 | $regKeyBeckhoff = $regKeyWow6432 + "Beckhoff\" 78 | $regKeyTc = $regKeyBeckhoff + "TwinCAT3\" 79 | $regKeyTcSystem = $regKeyTc + "System" 80 | $regKeyPropertyAmsNetId = "AmsNetId" 81 | 82 | # Check if Beckhoff RegKey exists (does not exist on systems without TwinCAT) 83 | if (Test-Path $regKeyTcSystem) { 84 | # Reading current AmsNetId from Windows Registry 85 | $amsNetId = Get-ItemProperty -Path $regKeyTcSystem -Name $regKeyPropertyAmsNetId 86 | 87 | # Using the IP address 88 | $ipAddrArr = $ipAddr.Split(".") 89 | 90 | # Stopping TwinCAT System Service and all dependencies 91 | Stop-Service -Name "TcSysSrv" -Force 92 | 93 | # Setting new AMS Net ID based on local IP address, the last two bytes from old AMS Net ID are kept 94 | $amsNetId.AmsNetId[0] = $ipAddrArr[0] 95 | $amsNetId.AmsNetId[1] = $ipAddrArr[1] 96 | $amsNetId.AmsNetId[2] = $ipAddrArr[2] 97 | $amsNetId.AmsNetId[3] = $ipAddrArr[3] 98 | Set-ItemProperty -Path $regKeyTcSystem -Name $regKeyPropertyAmsNetId -Value $amsNetId.AmsNetId 99 | 100 | # Starting TwinCAT System Service 101 | Start-Service -Name "TcSysSrv" 102 | } 103 | ``` 104 | Install EtherCAT Driver with TwinCAT RTE Install: 105 | ``` 106 | $adapter_name = "Ethernet1" 107 | 108 | # Install driver for adapter 109 | Start-Process -Wait C:\TwinCAT\3.1\System\TcRteInstall.exe -ArgumentList "-installnic $adapter_name /S" -PassThru 110 | ``` 111 | 112 | 113 | -------------------------------------------------------------------------------- /DeviceLockdown_Sample/Reset_All_DeviceLockdownFeatures.ps1: -------------------------------------------------------------------------------- 1 | ########################## 2 | # Define global Variable 3 | $username = "Operator" 4 | $Global:ShellLauncherClass=$null 5 | $CommonParams = @{ "namespace" = "root\standardcimv2\embedded" }; 6 | if ($PSBoundParameters.ContainsKey("ComputerName")) 7 | { 8 | $CommonParams += @{ "ComputerName" = $ComputerName }; 9 | } 10 | ########################## 11 | 12 | # Log the actions of the Script in a Log File 13 | Function Log-Message() 14 | { 15 | param 16 | ( 17 | [Parameter(Mandatory=$true)] [string] $Message 18 | ) 19 | 20 | Try { 21 | 22 | #Get the Location of the script 23 | If ($psise) { 24 | $CurrentDir = Split-Path $psise.CurrentFile.FullPath 25 | } 26 | Else { 27 | $CurrentDir = $PSScriptRoot 28 | } 29 | 30 | #Frame Log File with Current Directory and date 31 | $LogFile = $CurrentDir+ "\" + "Device_Lockdown_Log.txt" 32 | 33 | #Add Content to the Log File 34 | $TimeStamp = (Get-Date).toString("dd/MM/yyyy HH:mm:ss:fff tt") 35 | $Line = "$TimeStamp - $Message" 36 | Add-content -Path $Logfile -Value $Line 37 | 38 | Write-host "Message: '$Message' Has been Logged to File: $LogFile" 39 | } 40 | Catch { 41 | Write-host -f Red "Error:" $_.Exception.Message 42 | } 43 | } 44 | 45 | # Create a function to retrieve the SID for a user account on a machine. 46 | function Get-UsernameSID($AccountName) { 47 | 48 | $NTUserObject = New-Object System.Security.Principal.NTAccount($AccountName) 49 | $NTUserSID = $NTUserObject.Translate([System.Security.Principal.SecurityIdentifier]) 50 | 51 | return $NTUserSID.Value 52 | } 53 | 54 | ##########-----------The script starts here---------################## 55 | Log-Message("---------------------------------------") 56 | 57 | #Disable keyboard filter feature without restart 58 | Disable-WindowsOptionalFeature -Online -FeatureName Client-KeyboardFilter -NoRestart -OutVariable result 59 | 60 | #Detect if restart is needed 61 | if ($result.RestartNeeded -eq $true) 62 | { 63 | $restartneeded = $true 64 | Log-Message ("Required restart for disable the Keyboard Filter") 65 | } 66 | 67 | $NAMESPACE= $CommonParams.namespace 68 | $COMPUTER=$CommonParams.ComputerName 69 | $Global:ShellLauncherClass = [wmiclass]"\$COMPUTER${NAMESPACE}:WESL_UserSetting" 70 | # This security identifier (SID) responds to the BUILTIN\Administrators group. 71 | 72 | $Admins_SID = "S-1-5-32-544" 73 | 74 | 75 | # Get the SID for a user account. Rename "Operator" to an existing account on your system to test this script. 76 | 77 | $Operator_SID = Get-UsernameSID($username) 78 | 79 | # Remove the new custom shells. 80 | 81 | $Global:ShellLauncherClass.RemoveCustomShell($Admins_SID) 82 | 83 | $Global:ShellLauncherClass.RemoveCustomShell($Operator_SID) 84 | 85 | #Disable Shell Launcher 86 | $Global:ShellLauncherClass.SetEnabled($FALSE) 87 | 88 | $IsShellLauncherEnabled = $Global:ShellLauncherClass.IsEnabled() 89 | 90 | Log-Message ("Shell Launcher Status is set to " + $IsShellLauncherEnabled.Enabled) 91 | #Disable shell launcher feature without restart 92 | Disable-WindowsOptionalFeature -Online -FeatureName Client-EmbeddedShellLauncher -NoRestart -OutVariable result 93 | 94 | 95 | #Detect if restart is needed 96 | if ($result.RestartNeeded -eq $true) 97 | { 98 | $restartneeded = $true 99 | Log-Message ("Required restart for disable the Shell Launcher") 100 | } 101 | 102 | #Disable Unbranded Boot feature without restart 103 | Disable-WindowsOptionalFeature -Online -FeatureName Client-EmbeddedBootExp -NoRestart -OutVariable result 104 | 105 | #Detect if restart is needed 106 | if ($result.RestartNeeded -eq $true) 107 | { 108 | $restartneeded = $true 109 | Log-Message ("Required restart for disable the Unbranded Boot") 110 | } 111 | 112 | #Disable Custom Logon feature without restart 113 | Disable-WindowsOptionalFeature -Online -FeatureName Client-EmbeddedLogon -NoRestart -OutVariable result 114 | 115 | #Detect if restart is needed 116 | if ($result.RestartNeeded -eq $true) 117 | { 118 | $restartneeded = $true 119 | Log-Message ("Required restart for disable the Custom Logon") 120 | } 121 | 122 | 123 | #If feature uninstalled and required restart, then restart 124 | if ($restartneeded -eq $true) 125 | { 126 | Restart-Computer -Confirm:$true -Force 127 | Exit 128 | } -------------------------------------------------------------------------------- /DeviceLockdown_Sample/README.md: -------------------------------------------------------------------------------- 1 | # Device Lockdown Features 2 | 3 | The Device Lockdown Features allow you to lock down your Windows System. 4 | This can be useful to protect the system from malicious users or customize the user experience. 5 | 6 | The Device Lockdown Features are described here: 7 | 8 | - [Shell Launcher](#shell-launcher) 9 | 10 | - [Unbranded Boot](#unbranded-boot) 11 | 12 | - [Keyboard Filter](#keyboard-filter) 13 | 14 | - [Custom Logon](#custom-logon) 15 | 16 | 17 | 18 | 19 | 20 | 21 | ## Shell Launcher 22 | You can use Shell Launcher to configure a custom Shell for a specific Windows User. This script creates a new user and defines any application as custom shell to the user. 23 | 24 | You have to define a username and password for the new user. The new user is logged on automatically after system starts. 25 | ``` 26 | # Shell Launcher 27 | $ConfigureShellLauncher=$TRUE 28 | $ConfigNewUser=$TRUE #Resets existing user and creates a new one with user rights and configered Autologon 29 | $username = "Operator" 30 | $password = "1" 31 | $customShellApp="C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe --kiosk www.beckhoff.com --edge-kiosk-type=fullscreen" 32 | ``` 33 | 34 | You can define an action that should happen after closing the shell: 35 | 36 | | **Action** | **Description** | 37 | |------------|-------------------| 38 | | 0 | Restart the shell | 39 | | 1 | Restart the IPC | 40 | | 2 | Shut down the IPC | 41 | | 3 | Do nothing | 42 | ``` 43 | # Define actions to take when the shell program exits. 44 | $Shell_Launcher_Exit_Action = 0 # Restart Shell 45 | #$Shell_Launcher_Exit_Action = 1 # Restart Device 46 | #$Shell_Launcher_Exit_Action = 2 # Shutdown Device 47 | #$Shell_Launcher_Exit_Action = 3 # Do Nothing 48 | ``` 49 | 50 | You can define a Breakout Key with the [Keyboard Filter](#keyboard-filter) to switch to the Welcome Screen. Otherwise, you can implement an exit strategy in your HMI. For example you can the run following command to log off the current user: 51 | ``` 52 | C:\Windows\System32\rundll32.exe user32.dll, LockWorkStation 53 | ``` 54 | 55 | Offical Microsoft Documentation: 56 | 57 | https://learn.microsoft.com/en-us/windows-hardware/customize/enterprise/shell-launcher 58 | 59 | ## Unbranded Boot 60 | 61 | You can suspress Windows elements during the boot phase with Unbranded Boot: 62 | 63 | Before Unbranded Boot: 64 | 65 | 66 | 67 | After Unbranded Boot: 68 | 69 | 70 | 71 | You can replace the startup logo with a custom BIOS with an adapted boot screen. The UEFI boot mode is required for this. 72 | 73 | Official Microsoft Documentation: 74 | 75 | https://learn.microsoft.com/en-us/windows-hardware/customize/enterprise/unbranded-boot 76 | 77 | ## Keyboard Filter 78 | Filter undesirable key presses or key combinations with the Keyboard Filter. This helps to block key combinations like Ctrl+Alt+Delete. 79 | You can exclude the Administrator from these policies. 80 | 81 | In addition a Breakout Key is configured. This setting specifies the scan code of the key that enables a user to break out of an account that is locked down with Keyboard Filter. A user can press this key consecutively five times to switch to the Welcome screen. The scan code of a key can be looked up here: 82 | https://kbdlayout.info/KBDGR/scancodes?arrangement=ISO105 83 | 84 | By default, the BreakoutKeyScanCode is set to the scan code for the left Windows logo key ((HEX=5B, DEC=91)) 85 | ``` 86 | # Keyboard Filter 87 | $ConfigureKeyboardFilter=$TRUE 88 | $FilteredKeys=@("Ctrl+Alt+Del","Win+L","Win+E","Win+R") 89 | $BreakoutKey="91" #in DEC 90 | $DisableKeyboardFilterForAdministrator=$TRUE 91 | ``` 92 | Official Microsoft Documentation: 93 | 94 | https://learn.microsoft.com/en-us/windows-hardware/customize/enterprise/keyboardfilter 95 | 96 | 97 | ## Custom Logon 98 | Custom Logon allows you to disable Windows user logon animations: 99 | Auto Logon UI: 100 | 101 | 102 | 103 | Hide Auto Logon UI: 104 | 105 | 106 | 107 | It's also possible to remove the buttons form the Welcome screen. 108 | 109 | Welcome screen: 110 | 111 | 112 | 113 | Welcome screen with Branding Neutral: 114 | 115 | 116 | 117 | 118 | ``` 119 | # Custom Logon 120 | $ConfigureCustomLogon=$TRUE 121 | $HideAutoLogonUI=$TRUE 122 | $BrandingNeutral=$TRUE 123 | ``` 124 | 125 | Official Microsoft Documentation: 126 | 127 | https://learn.microsoft.com/en-us/windows-hardware/customize/enterprise/custom-logon -------------------------------------------------------------------------------- /ConfigureBasicSystem_Sample/Windows/README.md: -------------------------------------------------------------------------------- 1 | # ConfigureBasicSystem 2 | 3 | There are some basic settings that are useful to get started with a Beckhoff Windows System quickly. We provide sample scripts for the following settings: 4 | 5 | • Create administrator and user accounts 6 | • Set administrator and user password 7 | • Enable or disable auto login 8 | • Configure Firewall (turn on, disable rules, block traffic) 9 | • Enable or disable RDP 10 | • Open Firewall ports 11 | 12 | 13 | ## Create user accounts, set Passwords and configure auto login 14 | 15 | Create new Administrator account with name "SystemAdministrator": 16 | ``` 17 | $username = "SystemAdministrator" 18 | $password = "adminpw" 19 | $passwordSec = ConvertTo-SecureString -String $password -AsPlainText -Force 20 | 21 | # Create new user account if it does not exist 22 | $account = Get-LocalUser -Name $username -ErrorAction SilentlyContinue 23 | if (-not ($null -eq $account)) { 24 | Remove-LocalUser -Name $username 25 | } 26 | New-LocalUser -Name $username -FullName $username -Description "System Administrator" -Password $passwordSec 27 | 28 | # Make the user part of the Administrators Group 29 | Add-LocalGroupMember -Group "Administrators" -Member $username 30 | ``` 31 | Change Administrator Password: 32 | ``` 33 | $username = "SystemAdministrator" 34 | $password = "TwinCAT123" 35 | $passwordSec = ConvertTo-SecureString -String $password -AsPlainText -Force 36 | 37 | # Create new user account if it does not exist 38 | $account = Get-LocalUser -Name $username -ErrorAction SilentlyContinue 39 | # Change Password if User Exists 40 | if (-not ($null -eq $account)) { 41 | $account = Get-LocalUser -Name $username 42 | $account | Set-LocalUser -Password $passwordSec 43 | } 44 | else { 45 | Write-Host "User named $username does not exist" 46 | } 47 | ``` 48 | Create unprivileged user account with name "TwinCAT_User" 49 | 50 | ``` 51 | $username = "TwinCAT_User" 52 | $password = "userpw" 53 | $passwordSec = ConvertTo-SecureString -String $password -AsPlainText -Force 54 | 55 | # Create new user account if it does not exist 56 | $account = Get-LocalUser -Name $username -ErrorAction SilentlyContinue 57 | if (-not ($null -eq $account)) { 58 | Remove-LocalUser -Name $username 59 | } 60 | New-LocalUser -Name $username -FullName $username -Description "Standard Windows user" -Password $passwordSec 61 | 62 | # Make the user part of the Administrators Group 63 | Add-LocalGroupMember -Group "Users" -Member $username 64 | ``` 65 | Enable Autologin 66 | ``` 67 | $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" 68 | $DefaultUsername = "SystemAdministrator" 69 | $DefaultPassword = "adminpw" 70 | 71 | Set-ItemProperty $RegPath "AutoAdminLogon" -Value "1" -type String 72 | Set-ItemProperty $RegPath "DefaultUsername" -Value "$DefaultUsername" -type String 73 | Set-ItemProperty $RegPath "DefaultPassword" -Value "$DefaultPassword" -type String 74 | ``` 75 | 76 | Disable auto login: 77 | 78 | ``` 79 | $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" 80 | 81 | Set-ItemProperty $RegPath "AutoAdminLogon" -Value "0" -type String 82 | ``` 83 | 84 | ## Configure Firewall 85 | Configure and turn on firewall: 86 | ``` 87 | #Enable firewall 88 | Set-NetFirewallProfile -Profile Domain, Public, Private -Enabled True 89 | 90 | #Close inbound and Outbound traffic 91 | Set-NetFirewallProfile -DefaultInboundAction Block -DefaultOutboundAction Block –NotifyOnListen True 92 | 93 | #Disable all current firewall rules 94 | Get-NetFirewallRule | Set-NetFirewallRule -Enabled False 95 | ``` 96 | Open firewall ports: 97 | ``` 98 | #Allow ADS (TCP) (port 48898) 99 | New-NetFirewallRule -DisplayName 'TwinCAT ADS (TCP)' ` 100 | -Profile @('Domain', 'Private') ` 101 | -Direction Inbound ` 102 | -Action Allow ` 103 | -Protocol TCP ` 104 | -LocalPort 48898 105 | 106 | New-NetFirewallRule -DisplayName 'TwinCAT ADS (TCP)' ` 107 | -Profile @('Domain', 'Private') ` 108 | -Direction Outbound ` 109 | -Action Allow ` 110 | -Protocol TCP ` 111 | -LocalPort 48898 112 | 113 | ``` 114 | 115 | Enable RDP: 116 | ``` 117 | # Enable RDP in Registry 118 | Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -name "fDenyTSConnections" -value 0 119 | 120 | # Allow RDP TCP-In (port 3389) 121 | if($(Get-NetFirewallRule -DisplayName 'Remote Desktop - User Mode (TCP-In)')) 122 | { 123 | Set-NetFirewallRule -DisplayName 'Remote Desktop - User Mode (TCP-In)' -Enabled True 124 | } 125 | else 126 | { 127 | New-NetFirewallRule -DisplayName 'Remote Desktop - User Mode (TCP-In)' ` 128 | -Profile Any ` 129 | -Direction Inbound ` 130 | -Action Allow ` 131 | -Protocol TCP ` 132 | -LocalPort 3389 133 | } 134 | ``` 135 | Disable RDP: 136 | ``` 137 | # Disable RDP in Registry 138 | Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -name "fDenyTSConnections" -value 1 139 | 140 | # Block RDP TCP-In (port 3389) 141 | if($(Get-NetFirewallRule -DisplayName 'Remote Desktop - User Mode (TCP-In)')) 142 | { 143 | Set-NetFirewallRule -DisplayName 'Remote Desktop - User Mode (TCP-In)' -Enabled False 144 | } 145 | else 146 | { 147 | New-NetFirewallRule -DisplayName 'Remote Desktop - User Mode (TCP-In)' ` 148 | -Profile Any ` 149 | -Direction Inbound ` 150 | -Action Block ` 151 | -Protocol TCP ` 152 | -LocalPort 3389 153 | } 154 | ``` -------------------------------------------------------------------------------- /SilentInstallation_Samples/readme.md: -------------------------------------------------------------------------------- 1 | # Silent Installation Parameters for TwinCAT 3.1 Build 4024 (XAE/XAR) 2 | 3 | During installation, make sure that the silent installation is carried out with an administrator account and not with the Windows account NT_AUTHORITY_SYSTEM. The installation is supposedly carried out successfully, but can subsequently lead to side effects. 4 | 5 | The samples listed below list actual installation file versions. New versions may behave differently and there is no claim to completeness. 6 | 7 | Remark: 8 | Sometimes a parameter "REBOOT=ReallySuppress" is used. It suppresses all reboots and reboot prompts at the end of the installation. The installation is properly finished after a reboot of all silent installations. 9 | 10 | **TwinCAT Engineering (XAE) without Git:** 11 | ``` 12 | TC31-FULL-Setup.3.1.4024.55.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1 ACTIVATETCXAESHELLSETTINGS=1" 13 | ``` 14 | 15 | **TwinCAT Engineering (XAE) with Git:** 16 | ``` 17 | TC31-FULL-Setup.3.1.4024.55.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1 ACTIVATETCXAESHELLSETTINGS=1 GIT_FOR_WINDOWS_MINIMAL_INSTALL_AND_ACCEPT_LICENSE=1"" 18 | ``` 19 | 20 | **TwinCAT Runtime (XAR):** 21 | ``` 22 | TC31-XAR-Setup.3.1.4024.55.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 23 | ``` 24 | 25 | 26 | # Silent Installation Parameters for TwinCAT Functions for TwinCAT 3.1 Build 4024 27 | 28 | **TF1810 | TwinCAT 3 PLC HMI Web** 29 | ``` 30 | TF1810_1.7.5.1.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 31 | ``` 32 | 33 | **TF2000 | TwinCAT 3 HMI Server (32 Bit)** 34 | ``` 35 | TF2000_1.12.760.59.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 36 | ``` 37 | 38 | **TF2000 | TwinCAT 3 HMI Server (64 Bit)** 39 | ``` 40 | TF2000_1.12.760.59.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1 HMISERVERARCHITECTURE=64" 41 | ``` 42 | 43 | **TF3300 | TwinCAT 3 Scope Server (XAE)** 44 | ``` 45 | TF3300 XAE_3.4.3148.15.exe /silent 46 | ``` 47 | 48 | **TF3300 | TwinCAT 3 Scope Server (XAR)** 49 | ``` 50 | TF3300 XAR_3.4.3148.15.exe /silent 51 | ``` 52 | 53 | **TF3520 | TwinCAT 3 Analytics Storage Provider** 54 | ``` 55 | TF3520 Analytics Storage Provider_1.0.12.3.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 56 | ``` 57 | 58 | **TF3600 | TwinCAT 3 Condition Monitoring** 59 | ``` 60 | TF3600_3.2.27.2.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 61 | ``` 62 | 63 | **TF3650 | TwinCAT 3 Power Monitoring** 64 | ``` 65 | TF3650 TC3 Power Monitoring_3.2.33.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 66 | ``` 67 | 68 | **TF3680 | TwinCAT 3 Filter** 69 | ``` 70 | TF3680_XAE_1.1.8.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 71 | ``` 72 | 73 | **TF3800 | TwinCAT 3 Machine Learning Inference Engine** 74 | ``` 75 | TF38xx-Machine-Learning_3.1.62.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 76 | ``` 77 | 78 | **TF4100 | TwinCAT 3 Controller Toolbox** 79 | ``` 80 | TF4100_3.4.1.4.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 81 | ``` 82 | 83 | **TF4110 | TwinCAT 3 Temperature Controller** 84 | ``` 85 | TF4110_3.3.2.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 86 | ``` 87 | 88 | **TF4500 | TwinCAT 3 Speech** 89 | ``` 90 | TF4500_1.1.8.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 91 | ``` 92 | 93 | **TF511x | TwinCAT 3 KinematicTransformation** 94 | ``` 95 | TF511x_3.1.3.21.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1 INSTALLTOTC31=1" 96 | ``` 97 | 98 | **TF5200 | TwinCAT 3 CNC** 99 | ``` 100 | TF5200 CNC_3.1.3079.20.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 101 | ``` 102 | 103 | **TF5270 | TwinCAT 3 CNC Virtual NCK Basis** 104 | ``` 105 | TF527x_1.0.6.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 106 | ``` 107 | 108 | **TF5400 | TwinCAT 3 Advanced Motion Pack** 109 | ``` 110 | TF54xx_3.2.38.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 111 | ``` 112 | 113 | **TF5850 | TwinCAT 3 XTS Extension** 114 | ``` 115 | TF5850 XTS Technology_3.22.1011.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 116 | ``` 117 | 118 | **TF5890 | TwinCAT 3 XPlanar** 119 | ``` 120 | TF5890_3.2209.6.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 121 | ``` 122 | 123 | **TF6100 | TwinCAT 3 OPC UA** 124 | ``` 125 | TF6100-Client_4.4.38.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 126 | TF6100-OPC-UA-Gateway_4.4.4.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 127 | TF6100-Server_5.1.106.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 128 | ``` 129 | 130 | **TF6120 | TwinCAT 3 OPC DA** 131 | ``` 132 | TF6120_4.1.96.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 133 | ``` 134 | 135 | **TF6250 | TwinCAT 3 Modbus TCP** 136 | ``` 137 | TF6250_1.0.66.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 138 | ``` 139 | 140 | **TF6300 | TwinCAT 3 FTP Client** 141 | ``` 142 | TF6300_3.0.5.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 143 | ``` 144 | 145 | **TF6310 | TwinCAT 3 TCP/IP** 146 | ``` 147 | TF6310_3.3.20.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 148 | ``` 149 | 150 | **TF6350 | TwinCAT 3 SMS/SMTP** 151 | ``` 152 | TF6350_1.0.29.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 153 | ``` 154 | 155 | **TF6360 | TwinCAT 3 Virtual Serial COM** 156 | ``` 157 | TF6360_1.34.0.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 158 | ``` 159 | 160 | **TF6420 | TwinCAT 3 Database Server - Beckhoff** 161 | ``` 162 | TF6420_3.3.35.5.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 163 | ``` 164 | 165 | **TF6421 | TwinCAT 3 XML Server** 166 | ``` 167 | TF6421_3.2.32.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 168 | ``` 169 | 170 | **TF6510 | TwinCAT 3 IEC 61850/IEC 61400-25** 171 | ``` 172 | TF6510_3.1.97.3.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 173 | ``` 174 | 175 | **TF6600 | TwinCAT 3 RFID Reader Communication** 176 | ``` 177 | TF6600_1.0.3.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 178 | ``` 179 | 180 | **TF6620 | TwinCAT 3 S7 Communication** 181 | ``` 182 | TF6620_1.1.11.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 183 | ``` 184 | 185 | **TF6720 | TwinCAT 3 IoT Data Agent** 186 | ``` 187 | TF6720 IoT Data Agent_1.2.46.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 188 | ``` 189 | 190 | **TF7xxx | TwinCAT 3 Vision** 191 | ``` 192 | TF7xxx Functions_4.0.3.5.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 193 | ``` 194 | 195 | **TF8010 | TwinCAT 3 Building Automation Basic** 196 | ``` 197 | TF8010 - TC3 Building Automation Basic_3.1.2.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 198 | ``` 199 | 200 | **TF8040 | TwinCAT 3 Building Automation** 201 | ``` 202 | TF8040 XAE_5.6.0.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 203 | ``` 204 | 205 | **TF8310 | TwinCAT 3 Wind Framework - Beckhoff** 206 | ``` 207 | TF8310_3.1.1.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 208 | ``` 209 | 210 | **TF8810 | TwinCAT 3 AES70 (OCA)** 211 | ``` 212 | TF8810_1.0.3.0.exe /s /clone_wait /v"/qr REBOOT=ReallySuppress ALLUSERS=1" 213 | ``` 214 | -------------------------------------------------------------------------------- /Bitlocker_Samples/Enable_Bitlocker.ps1: -------------------------------------------------------------------------------- 1 | # Bitlocker Sample Script 2 | # Version 0.5 3 | 4 | # 5 | # Write-Log function 6 | # 7 | function Write-Log { 8 | [CmdletBinding()] 9 | param( 10 | [Parameter(Mandatory=$true)] 11 | [ValidateNotNullOrEmpty()] 12 | [ValidateSet('Info','Warning','Error')] 13 | [string]$Severity, 14 | 15 | [Parameter(Mandatory=$true)] 16 | [ValidateNotNullOrEmpty()] 17 | [string]$Message 18 | ) 19 | 20 | [pscustomobject]@{ 21 | Time = (Get-Date -Format "yyyy-MM-dd HH:mm") 22 | Severity = $Severity 23 | Message = $Message 24 | } | Export-Csv -Path "$env:Temp\LogFile.csv" -Append -NoTypeInformation 25 | } 26 | 27 | # 28 | # Variables declaration 29 | # 30 | $FirmwareType = $env:firmware_type 31 | $OSArchitecture = (Get-CimInstance -ClassName CIM_OperatingSystem).OSArchitecture 32 | $OSReleaseId = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").ReleaseId 33 | $TPMPresent = [bool](Get-WmiObject -class WIN32_TPM -Namespace root\CIMv2\Security\Microsofttpm).IsEnabled_InitialValue 34 | $TPMReady = [bool](Get-WmiObject -class WIN32_TPM -Namespace root\CIMv2\Security\Microsofttpm).IsActivated_InitialValue 35 | $BitLockerReadyDrive = (Get-BitLockerVolume -MountPoint $env:SystemDrive -ErrorAction SilentlyContinue).MountPoint 36 | $BitLockerDecrypted = (Get-BitLockerVolume -MountPoint $env:SystemDrive -ErrorAction SilentlyContinue).VolumeStatus 37 | $KeyProtectorLocation = "C:\Users\Administrator\Desktop\KeyProtector.txt" 38 | $TwinCATSysService = (Get-Service -Name TcSysSrv -ErrorAction SilentlyContinue).Status 39 | 40 | # 41 | # Define exit codes 42 | # 43 | $Error_Success = 0 44 | $Error_OsLegacy = 10 45 | $Error_Os32Bit = 11 46 | $Error_OsReleaseId = 12 47 | $Error_TpmNotPreent = 20 48 | $Error_TpmNotReady = 21 49 | $Error_BLDriveNotReady = 30 50 | $Error_BLEncryptionInProgress = 31 51 | $Error_BLDecryptionInProgress = 32 52 | $Error_BLFullyEncrypted = 32 53 | $Error_TcSysPsExtensionMissing = 40 54 | $Error_TcSysStateRunning = 41 55 | 56 | # 57 | # Check if TwinCAT system service is available and running 58 | # Import TwinCAT AdsApi powershell module 59 | # Check if TwinCAT is in CONFIG mode 60 | # 61 | if ($TwinCATSysService -eq "Running") 62 | { 63 | if ([bool](Test-Path HKLM:\SYSTEM\CurrentControlSet\Services\TcSysSrv\)) 64 | { 65 | $TCPowerShellExt = [System.IO.Path]::GetDirectoryName((Get-ItemPropertyValue -Path "HKLM:\SOFTWARE\WOW6432Node\Beckhoff\TwinCAT3\" -Name "TwinCATDir") -replace '"') 66 | $TCPowerShellExt += '\AdsApi\Powershell\TcXaeMgmt\TcXaeMgmt.psd1' 67 | if (Test-Path $TCPowerShellExt) 68 | { 69 | Import-Module $TCPowerShellExt 70 | $TCSystemState = (Get-AdsState).State 71 | if ($TCSystemState -ne "Config") 72 | { 73 | Write-Host "TwinCAT is in RUN mode. Bitlocker can not be enabled." 74 | Write-Log -Message "TwinCAT is in RUN mode. Bitlocker can not be enabled." -Severity Error 75 | Exit $Error_TcSysStateRunning 76 | } 77 | } 78 | else 79 | { 80 | Write-Host "TwinCAT AdsApi powershell extension not found." 81 | Write-Log -Message "TwinCAT AdsApi powershell extension not found." -Severity Error 82 | Exit $Error_TcSysPsExtensionMissing 83 | } 84 | } 85 | } 86 | 87 | # 88 | # Check if boot mode is UEFI or LEGACY 89 | # 90 | if ($FirmwareType -ne "UEFI") 91 | { 92 | Write-Host "OS Boot Mode is LEGACY." 93 | Write-Host "TPM is not supported with this Boot Mode." 94 | Write-Log -Message "OS Boot Mode is LEGACY." -Severity Error 95 | Write-Log -Message "TPM is not supported with this Boot Mode." -Severity Error 96 | Exit $Error_OsLegacy 97 | } else { 98 | Write-Host "OS boot mode is UEFI" 99 | Write-Log -Message "OS boot mode is UEFI" -Severity Info 100 | } 101 | 102 | # 103 | # Check if architecture is 32 Bit or 64 Bit 104 | # 105 | if ($OSArchitecture -ne "64-bit") 106 | { 107 | Write-Host "OS architecture is 32 bit" 108 | Write-Host "TPM is not supported with this OS architecture" 109 | Write-Log -Message "OS architecture is 32 bit" -Severity Error 110 | Write-Log -Message "TPM is not supported with this OS architecture" -Severity Error 111 | Exit $Error_Os32Bit 112 | } else { 113 | Write-Host "OS architecture is 64 bit" 114 | Write-Log -Message "OS architecture is 64 bit" -Severity Info 115 | } 116 | 117 | # 118 | # Check if OS release id is supported (below 1809 is not supported) 119 | # 120 | if ($OSReleaseId -lt '1809') 121 | { 122 | Write-Host "OS ReleaseId is lower than 1809 and will not be supported" 123 | Write-Log -Message "OS ReleaseId is lower than 1809 and will not be supported" -Severity Error 124 | Exit $Error_OsReleaseId 125 | } else { 126 | Write-Host "OS ReleaseId is supported." 127 | Write-Log -Message "OS ReleaseId is supported." -Severity Info 128 | } 129 | 130 | # 131 | # Check if TPMPresent is true 132 | # 133 | if (!$TPMPresent) 134 | { 135 | Write-Host "TPM is not present. Please check the BIOS settings (Trusted Platform)" 136 | Write-Log -Message "TPM is not present. Please check the BIOS settings (Trusted Platform)" -Severity Error 137 | Exit $Error_TpmNotPreent 138 | } else { 139 | Write-Host "TPM is present" 140 | Write-Log -Message "TPM is present" -Severity Info 141 | } 142 | 143 | # 144 | # Check if TPM is ready 145 | # 146 | if (!$TPMReady) 147 | { 148 | Write-Host "TPM is not ready" 149 | Write-Log -Message "TPM is not ready" -Severity Error 150 | Exit $Error_TpmNotReady 151 | } else { 152 | Write-Host "TPM is ready" 153 | Write-Log -Message "TPM is ready" -Severity Info 154 | } 155 | 156 | # 157 | # Check if MountPoint exists 158 | # 159 | if (!$BitLockerReadyDrive) 160 | { 161 | Write-Host "Bitlocker MountPoint does not exist" 162 | Write-Log -Message "Bitlocker MountPoint does not exist" -Severity Error 163 | Exit $Error_BLDriveNotReady 164 | } else { 165 | Write-Host "Bitlocker MountPoint exists" 166 | Write-Log -Message "Bitlocker MountPoint exists" -Severity Info 167 | } 168 | 169 | 170 | # 171 | # Check Bitlocker status states 172 | # 173 | switch ($BitLockerDecrypted) 174 | { 175 | "FullyDecrypted" { 176 | Write-Host "Bitlocker volume is fully decrypted" 177 | Write-Log -Message "Bitlocker volume is fully decrypted" -Severity Info} 178 | "EncryptionInProgress" { 179 | Write-Host "Bitlocker volume encryption is in progress. Stopping at this point." 180 | Write-Log -Message "Bitlocker volume encryption is in progress. Stopping at this point." -Severity Error 181 | Exit $Error_BLEncryptionInProgress} 182 | "DecryptionInProgress" { 183 | Write-Host "Bitlocker volume decryption is in progress. Stopping at this point" 184 | Write-Log -Message "Bitlocker volume decryption is in progress. Stopping at this point" -Severity Error 185 | Exit $Error_BLDecryptionInProgress} 186 | "FullyEncrypted" { 187 | Write-Host "Bitlocker volume is already encrypted. Stopping at this point." 188 | Write-Log "Bitlocker volume is already encrypted. Stopping at this point." 189 | Exit $Error_BLFullyEncrypted} 190 | } 191 | 192 | # 193 | # Add Bitlocker Protectors 194 | # 195 | Add-BitLockerKeyProtector -MountPoint $env:SystemDrive -TpmProtector -ErrorAction SilentlyContinue 196 | Write-Log -Message "Adding Bitlocker TpmProtector" -Severity Info 197 | Add-BitLockerKeyProtector -MountPoint $env:SystemDrive -RecoveryPasswordProtector -ErrorAction SilentlyContinue 198 | Write-Log -Message "Adding Bitlocker RecoveryPasswordProtector" -Severity Info 199 | 200 | # 201 | # Initialize TPM, add recovery partition if needed and enable Bitlocker 202 | # 203 | Initialize-Tpm -AllowClear -AllowPhysicalPresence 204 | BdeHdCfg -target $env:SystemDrive shrink -quiet 205 | Enable-BitLocker -MountPoint $env:SystemDrive -RecoveryPasswordProtector -EncryptionMethod Aes256 -UsedSpaceOnly 206 | Write-Log -Message "TPM initialized, recovery partition added if needed and Bitlocker enabled." -Severity Info 207 | 208 | # 209 | # Save Bitlocker KeyProtectors to defined target location 210 | # 211 | $KeyProtector = (Get-BitLockerVolume -MountPoint C).KeyProtector > $KeyProtectorLocation 212 | Write-Host "Saved Keyprotector to" $KeyProtectorLocation 213 | Write-Log -Message ("Saved Keyprotector to " + $KeyProtectorLocation) -Severity Info 214 | 215 | # 216 | # Finish 217 | # 218 | Write-Host 219 | Write-Host "Bitlocker has been successfully enabled. Restart the system to start encryption." 220 | Write-Log -Message "Bitlocker has been successfully enabled. Restart the system to start encryption." -Severity Info 221 | Exit $Error_Success -------------------------------------------------------------------------------- /WindowsUpdates_Sample/InstallWindowsUpdates.ps1: -------------------------------------------------------------------------------- 1 | # Steps considered in this script are 2 | # UWF filter status 3 | # Volume free space 4 | # Windows Update Service 5 | # Directory exist C:\WinUpdate\[SSU] \[MSU] \[.NET] 6 | # Windows Updates properly installed 7 | # Remove properly installed Windows Updates installation files C:\WinUpdate\[SSU] \[MSU] \[.NET] 8 | 9 | # 2021 LTSC and 2019 LTSC contain SSU (servicing stack update), 2016 LTSB needs separate SSU file 10 | # +-----------------------------------------------------------------------------------------------------------------------+ 11 | # | Windows 10 IoT Enterprise 2021 LTSC | 12 | # +-----------------------------------------------------------------------------------------------------------------------+ 13 | # | Sample: windows10.0-kb5035845-x64_b4c28c9c57c35bac9226cde51685e41c281e40eb.msu | 14 | # | Already contains the SSU file | 15 | # +-----------------------------------------------------------------------------------------------------------------------+ 16 | # | .\windows10.0-kb5035845-x64_b4c28c9c57c35bac9226cde51685e41c281e40eb.msu: Windows10.0-KB5035845-x64.cab | 17 | # | .\windows10.0-kb5035845-x64_b4c28c9c57c35bac9226cde51685e41c281e40eb.msu: WSUSSCAN.cab | 18 | # | .\windows10.0-kb5035845-x64_b4c28c9c57c35bac9226cde51685e41c281e40eb.msu: Windows10.0-KB5035845-x64-pkgProperties.txt | 19 | # | .\windows10.0-kb5035845-x64_b4c28c9c57c35bac9226cde51685e41c281e40eb.msu: Windows10.0-KB5035845-x64_uup.xml | 20 | # | .\windows10.0-kb5035845-x64_b4c28c9c57c35bac9226cde51685e41c281e40eb.msu: SSU-19041.4163-x64.cab | 21 | # +-----------------------------------------------------------------------------------------------------------------------+ 22 | 23 | # +-----------------------------------------------------------------------------------------------------------------------+ 24 | # | Windows 10 IoT Enterprise 2019 LTSC | 25 | # +-----------------------------------------------------------------------------------------------------------------------+ 26 | # | Sample: windows10.0-kb5035849-x64_eb960a140cd0ba04dd175df1b3268295295bfefa.msu | 27 | # | Already contains the SSU file | 28 | # +-----------------------------------------------------------------------------------------------------------------------+ 29 | # | .\windows10.0-kb5035849-x64_eb960a140cd0ba04dd175df1b3268295295bfefa.msu: ssu-17763.5568-x64.cab | 30 | # | .\windows10.0-kb5035849-x64_eb960a140cd0ba04dd175df1b3268295295bfefa.msu: Windows10.0-KB5035849-x64.cab | 31 | # | .\windows10.0-kb5035849-x64_eb960a140cd0ba04dd175df1b3268295295bfefa.msu: Windows10.0-KB5035849-x64-pkgProperties.txt | 32 | # | .\windows10.0-kb5035849-x64_eb960a140cd0ba04dd175df1b3268295295bfefa.msu: Windows10.0-KB5035849-x64_uup.xml | 33 | # | .\windows10.0-kb5035849-x64_eb960a140cd0ba04dd175df1b3268295295bfefa.msu: WSUSSCAN.cab | 34 | # +-----------------------------------------------------------------------------------------------------------------------+ 35 | 36 | # +-----------------------------------------------------------------------------------------------------------------------+ 37 | # | Windows 10 IoT Enterprise 2016 LTSC | 38 | # +-----------------------------------------------------------------------------------------------------------------------+ 39 | # | Sample: windows10.0-kb5035855-x86_202e177079c6c7fb6a503ad49a8abd07e8991676.msu | 40 | # | Contains no SSU file | 41 | # +-----------------------------------------------------------------------------------------------------------------------+ 42 | # | .\windows10.0-kb5035855-x86_202e177079c6c7fb6a503ad49a8abd07e8991676.msu: WSUSSCAN.cab | 43 | # | .\windows10.0-kb5035855-x86_202e177079c6c7fb6a503ad49a8abd07e8991676.msu: Windows10.0-KB5035855-x86-pkgProperties.txt | 44 | # | .\windows10.0-kb5035855-x86_202e177079c6c7fb6a503ad49a8abd07e8991676.msu: Windows10.0-KB5035855-x86.xml | 45 | # | .\windows10.0-kb5035855-x86_202e177079c6c7fb6a503ad49a8abd07e8991676.msu: Windows10.0-KB5035855-x86.cab | 46 | # +-----------------------------------------------------------------------------------------------------------------------+ 47 | 48 | 49 | function InstallUpdate { 50 | param( 51 | [string]$UpdatePath 52 | ) 53 | 54 | if (-not (Test-Path $UpdatePath)) { 55 | Write-Host "FAIL: WindowsUpdateLocationDrive: $UpdatePath does not exist" 56 | return 57 | } 58 | 59 | $Component = "" 60 | switch -wildcard ($UpdatePath) { 61 | "*.NET*" { $Component = ".NET:"; break } 62 | "*SSU*" { $Component = "SSU :"; break } 63 | "*MSU*" { $Component = "MSU :"; break } 64 | } 65 | 66 | $updates = Get-ChildItem $UpdatePath | Select-Object -ExpandProperty Name 67 | 68 | foreach ($updatename in $updates) { 69 | $HotfixID = $updatename.SubString(12, 9).ToUpper() 70 | $UpdateFullPath = Join-Path -Path $UpdatePath -ChildPath $updatename 71 | Write-Host "$Component Installing $updatename" 72 | $process = Start-Process -FilePath "wusa.exe" -ArgumentList "$UpdateFullPath /quiet /norestart" -Wait -PassThru -NoNewWindow 73 | 74 | switch ($process.ExitCode) { 75 | 3010 { 76 | Write-Host "EXIT: Exit Code $($process.ExitCode) $HotfixID $updatename - Installation successful. Reboot required." } 77 | 2359302 { 78 | Write-Host "EXIT: Exit Code $($process.ExitCode) $HotfixID $updatename - Update already installed." } 79 | -2145124329 { 80 | Write-Host "FAIL: Exit Code $($process.ExitCode) $HotfixID $updatename - Update is not applicable to this OS. Removing file." 81 | Remove-Item -Path $UpdateFullPath -Force } 82 | 87 { 83 | Write-Host "FAIL: Exit Code $($process.ExitCode) $HotfixID $updatename - WUSA parameter not recognized or incorrect." 84 | # Loop until the WUSA process exits 85 | # If an update does not support the "/norestart" parameter, it will immediately exit with code 87 but process "wusa.exe" is running and installing the update. 86 | while (Get-Process -Name "wusa" -ErrorAction SilentlyContinue) { 87 | Write-Host "INFO: Waiting for WUSA process to finish..." 88 | Start-Sleep -Seconds 5 # Adjust the sleep time as needed 89 | } 90 | Write-Host "INFO: WUSA process has finished." 91 | } 92 | } 93 | 94 | if ((Get-CimInstance -ClassName Win32_QuickFixEngineering).HotFixID -contains $HotfixID) { 95 | Write-Host "INFO: $HotfixID installed successfully" 96 | Write-Host "DEL : $UpdateFullPath will be removed" 97 | if (Test-Path $UpdateFullPath) { 98 | Remove-Item -Path $UpdateFullPath -Force 99 | } 100 | } 101 | } 102 | } 103 | 104 | # Definitions 105 | $WindowsUpdateServiceName = "wuauserv" 106 | $WindowsUpdateServiceStatus = Get-Service -Name $WindowsUpdateServiceName 107 | $WindowsUpdateServiceStartType = $WindowsUpdateServiceStatus.StartType 108 | 109 | # Update Paths 110 | $WindowsUpdateLocationDrive = "C" 111 | $WindowsUpdateSSUPath=$WindowsUpdateLocationDrive+":\WinUpdates\SSU" 112 | $WindowsUpdateMSUPath=$WindowsUpdateLocationDrive+":\WinUpdates\MSU" 113 | $WindowsUpdateNETPath=$WindowsUpdateLocationDrive+":\WinUpdates\.NET" 114 | 115 | # Free Space 116 | $VolumeFreeSpace = (Get-Volume -DriveLetter $WindowsUpdateLocationDrive).SizeRemaining 117 | $VolumeMinFreeSpace = 10GB 118 | 119 | # Error Codes 120 | $ERR_SUCCESS = 0 121 | $ERR_UWF = 1 122 | $ERR_FREESPACE = 2 123 | $ERR_WINUPDATESVC = 3 124 | 125 | # Check UWF filter status 126 | $NAMESPACE = "root\standardcimv2\embedded" 127 | $UWFEnabled = (Get-WmiObject -Namespace $NAMESPACE -Class UWF_Filter).CurrentEnabled 128 | if ($UWFEnabled) { 129 | Write-Host "WARN: Unified Write Filter is enabled. Unable to install updates." 130 | exit $ERR_UWF 131 | } else { 132 | Write-Host "INFO: Unified Write Filter is not enabled." 133 | } 134 | 135 | # Check freespace available, at least 10 GB for Windows Update installation 136 | if ($VolumeFreeSpace -lt $VolumeMinFreespace) { 137 | Write-Host "WARN: Not enough free space as recommended ($VolumeMinFreespace)." 138 | exit $ERR_FREESPACE 139 | } else { 140 | Write-Host "INFO: Free space available: $VolumeFreeSpace Bytes" 141 | } 142 | 143 | # Check Windows Update Service Status, if not running start the service 144 | $WindowsUpdateServiceStatus = Get-Service -Name $WindowsUpdateServiceName 145 | 146 | if ($WindowsUpdateServiceStatus.StartType -eq "Disabled") { 147 | Write-Host "INFO: Windows Update Service is disabled." 148 | Set-Service -Name $WindowsUpdateServiceName -StartupType Automatic 149 | $DisabledWindowsUpdateServiceStatus = $true 150 | } 151 | 152 | if ($WindowsUpdateServiceStatus.Status -ne "Running") { 153 | Write-Host "INFO: Windows Update Service is $($WindowsUpdateServiceStatus.Status)." 154 | Start-Service $WindowsUpdateServiceName -ErrorAction SilentlyContinue 155 | $WindowsUpdateServiceStatus.WaitForStatus("Running", [timespan]::FromSeconds(10)) 156 | if ($WindowsUpdateServiceStatus.Status -eq "Running") { 157 | Write-Host "INFO: Windows Update Service is started." 158 | } else { 159 | Write-Host "ERR : Failed to start Windows Update Service." 160 | exit $ERR_WINUPDATESVC 161 | } 162 | } else { 163 | Write-Host "INFO: Windows Update Service is already started." 164 | } 165 | 166 | # Check if directory exist (\WinUpdate\) SSU / MSU / .NET and install existing updates 167 | InstallUpdate($WindowsUpdateSSUPath) 168 | InstallUpdate($WindowsUpdateMSUPath) 169 | InstallUpdate($WindowsUpdateNETPath) 170 | 171 | # Set Windows Update Service to its origin state if disabled 172 | if ($DisabledWindowsUpdateServiceStatus -eq $true) { 173 | Write-Host "INFO: Windows Update Service set to its original state (disabled)." 174 | Set-Service -Name $ServiceName -StartupType Disabled 175 | Stop-Service -Name $ServiceName -Force 176 | } -------------------------------------------------------------------------------- /DeviceLockdown_Sample/Configure_DeviceLockdown.ps1: -------------------------------------------------------------------------------- 1 | # Configures the Device Lockdown Features of Windows IoT Enterprsie 2 | # Version 1.7 3 | 4 | # Official Microsoft Documentation: 5 | # https://learn.microsoft.com/en-us/windows-hardware/customize/enterprise/shell-launcher 6 | # https://learn.microsoft.com/en-us/windows-hardware/customize/enterprise/keyboardfilter 7 | # https://learn.microsoft.com/en-us/windows-hardware/customize/enterprise/unbranded-boot 8 | # https://learn.microsoft.com/en-us/windows-hardware/customize/enterprise/custom-logon 9 | 10 | 11 | ########################## 12 | # Define Parameters 13 | ########################## 14 | # Shell Launcher 15 | $ConfigureShellLauncher=$TRUE 16 | $ConfigNewUser=$TRUE #Resets existing user and creates a new one with user rights and configered Autologon 17 | $username = "Operator" 18 | $password = "123" # The defined password must comply with the password policy. Default: Minimum password length = 3 characters 19 | $customShellApp="C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe --kiosk www.beckhoff.com --edge-kiosk-type=fullscreen" 20 | 21 | # Define actions to take when the shell program exits. 22 | $Shell_Launcher_Exit_Action = 0 # Restart Shell 23 | #$Shell_Launcher_Exit_Action = 1 # Restart Device 24 | #$Shell_Launcher_Exit_Action = 2 # Shutdown Device 25 | #$Shell_Launcher_Exit_Action = 3 # Do Nothing 26 | ########################### 27 | # Keyboard Filter 28 | $ConfigureKeyboardFilter=$TRUE 29 | $FilteredKeys=@("Ctrl+Alt+Del","Win+L","Win+E","Win+R") 30 | $BreakoutKey="91" #in DEC 31 | # This setting specifies the scan code of the key that enables a user to break out of an account that is locked down with Keyboard Filter. 32 | # A user can press this key consecutively five times to switch to the Welcome screen. 33 | # The scan code of the key can be looked up here: 34 | # https://kbdlayout.info/KBDGR/scancodes?arrangement=ISO105 35 | # By default, the BreakoutKeyScanCode is set to the scan code for the left Windows logo key (HEX=5B, DEC=91). 36 | $DisableKeyboardFilterForAdministrator=$TRUE 37 | ########################### 38 | # Unbranded Boot 39 | $ConfigureUnbrandedBoot=$TRUE 40 | ########################### 41 | # Custom Logon 42 | $ConfigureCustomLogon=$TRUE 43 | $HideAutoLogonUI=$TRUE 44 | $BrandingNeutral=$TRUE 45 | 46 | ########################## 47 | # Define global Variable 48 | $Global:ShellLauncherClass=$null 49 | $CommonParams = @{ "namespace" = "root\standardcimv2\embedded" }; 50 | if ($PSBoundParameters.ContainsKey("ComputerName")) 51 | { 52 | $CommonParams += @{ "ComputerName" = $ComputerName }; 53 | } 54 | ########################## 55 | 56 | # Create a function to retrieve the SID for a user account on a machine. 57 | function Get-UsernameSID($AccountName) { 58 | 59 | $NTUserObject = New-Object System.Security.Principal.NTAccount($AccountName) 60 | $NTUserSID = $NTUserObject.Translate([System.Security.Principal.SecurityIdentifier]) 61 | 62 | return $NTUserSID.Value 63 | } 64 | 65 | # Log the actions of the script in a log file 66 | Function Log-Message() 67 | { 68 | param 69 | ( 70 | [Parameter(Mandatory=$TRUE)] [string] $Message 71 | ) 72 | 73 | Try { 74 | 75 | # Get the location of the script 76 | If ($psise) { 77 | $CurrentDir = Split-Path $psise.CurrentFile.FullPath 78 | } 79 | Else { 80 | $CurrentDir = $PSScriptRoot 81 | } 82 | 83 | # Frame log file with current directory and date 84 | $LogFile = $CurrentDir+ "\" + "Device_Lockdown_Log.txt" 85 | 86 | # Add content to the log file 87 | $TimeStamp = (Get-Date).toString("dd/MM/yyyy HH:mm:ss:fff tt") 88 | $Line = "$TimeStamp - $Message" 89 | Add-content -Path $Logfile -Value $Line 90 | 91 | Write-host "Message: '$Message' Has been Logged to File: $LogFile" 92 | } 93 | Catch { 94 | Write-host -f Red "Error:" $_.Exception.Message 95 | } 96 | } 97 | # Enables the required Device Lockdown features 98 | function Enable-LockdownFeatures 99 | { 100 | if($ConfigureShellLauncher -eq $TRUE) 101 | { 102 | # Create a handle to the class instance to call the static methods 103 | try { 104 | 105 | $NAMESPACE= $CommonParams.namespace 106 | $COMPUTER=$CommonParams.ComputerName 107 | $Global:ShellLauncherClass = [wmiclass]"\$COMPUTER${NAMESPACE}:WESL_UserSetting" 108 | 109 | 110 | } catch [Exception] { 111 | Log-Message ("Shell Launcher is currently disabled") 112 | Log-Message ($_.Exception.Message) 113 | Enable-WindowsOptionalFeature -Online -FeatureName Client-EmbeddedShellLauncher -All -NoRestart -OutVariable result 114 | $Global:ShellLauncherClass = [wmiclass]"\$COMPUTER${NAMESPACE}:WESL_UserSetting" 115 | Log-Message ("Shell Launcher is enabled") 116 | } 117 | } 118 | if($ConfigureKeyboardFilter -eq $TRUE) 119 | { 120 | $featureName = "Client-KeyboardFilter" 121 | $featureStatus = Get-WindowsOptionalFeature -Online -FeatureName $featureName 122 | $isEnabled = $featureStatus.State -eq 'Enabled' 123 | if(!$isEnabled) 124 | { 125 | try 126 | { 127 | # Write event log 128 | Log-Message ("Keyboard Filter is currently disabled") 129 | 130 | # Enable keyboard filter feature without restart 131 | Enable-WindowsOptionalFeature -Online -FeatureName Client-KeyboardFilter -All -NoRestart -OutVariable result 132 | 133 | # Detect if restart is required 134 | if ($result.RestartNeeded -eq $TRUE) 135 | { 136 | $restartneeded = $TRUE 137 | Log-Message ("Required restart for enable the Keyboard Filter") 138 | } 139 | } 140 | catch 141 | { 142 | # Something went wrong, display the error details and write an error to the event log 143 | Log-Message ("$_.Exception.Message") 144 | } 145 | } 146 | } 147 | 148 | if($ConfigureUnbrandedBoot -eq $TRUE) 149 | { 150 | $featureName = "Client-EmbeddedBootExp" 151 | $featureStatus = Get-WindowsOptionalFeature -Online -FeatureName $featureName 152 | $isEnabled = $featureStatus.State -eq 'Enabled' 153 | if(!$isEnabled) 154 | { 155 | try 156 | { 157 | # Write event log 158 | Log-Message ("Unbranded Boot is currently disabled") 159 | 160 | # Enable Unbranded Boot feature without restart 161 | Enable-WindowsOptionalFeature -Online -FeatureName Client-EmbeddedBootExp -All -NoRestart -OutVariable result 162 | 163 | # Detect if restart is required 164 | if ($result.RestartNeeded -eq $TRUE) 165 | { 166 | $restartneeded = $TRUE 167 | Log-Message ("Required restart for enable the Unbranded Boot") 168 | } 169 | } 170 | catch 171 | { 172 | # Something went wrong, display the error details and write an error to the event log 173 | Log-Message ("$_.Exception.Message") 174 | } 175 | } 176 | } 177 | if($ConfigureCustomLogon -eq $TRUE) 178 | { 179 | $featureName = "Client-EmbeddedLogon" 180 | $featureStatus = Get-WindowsOptionalFeature -Online -FeatureName $featureName 181 | $isEnabled = $featureStatus.State -eq 'Enabled' 182 | if(!$isEnabled) 183 | { 184 | try 185 | { 186 | # Write event log 187 | Log-Message ("Custom Logon is currently disabled") 188 | 189 | # Enable Custom Logon feature without restart 190 | Enable-WindowsOptionalFeature -Online -FeatureName Client-EmbeddedLogon -All -NoRestart -OutVariable result 191 | 192 | # Detect if restart is required 193 | if ($result.RestartNeeded -eq $TRUE) 194 | { 195 | $restartneeded = $TRUE 196 | Log-Message ("Required restart for enable the Custom Logon") 197 | } 198 | } 199 | catch 200 | { 201 | # Something went wrong, display the error details and write an error to the event log 202 | Log-Message ("$_.Exception.Message") 203 | } 204 | } 205 | } 206 | 207 | # If feature installed and requires restart, then restart 208 | if ($restartneeded -eq $TRUE) 209 | { 210 | Restart-Computer -Confirm:$TRUE -Force 211 | Exit 212 | } 213 | 214 | } 215 | function Check-ShellLauncherLicenseEnabled 216 | { 217 | [string]$source = @" 218 | using System; 219 | using System.Runtime.InteropServices; 220 | 221 | static class CheckShellLauncherLicense 222 | { 223 | const int S_OK = 0; 224 | 225 | public static bool IsShellLauncherLicenseEnabled() 226 | { 227 | int enabled = 0; 228 | 229 | if (NativeMethods.SLGetWindowsInformationDWORD("EmbeddedFeature-ShellLauncher-Enabled", out enabled) != S_OK) { 230 | enabled = 0; 231 | } 232 | return (enabled != 0); 233 | } 234 | 235 | static class NativeMethods 236 | { 237 | [DllImport("Slc.dll")] 238 | internal static extern int SLGetWindowsInformationDWORD([MarshalAs(UnmanagedType.LPWStr)]string valueName, out int value); 239 | } 240 | 241 | } 242 | "@ 243 | 244 | $type = Add-Type -TypeDefinition $source -PassThru 245 | 246 | return $type[0]::IsShellLauncherLicenseEnabled() 247 | } 248 | # Create a new user and configure the Shell Launcher 249 | function Configure-ShellLauncher 250 | { 251 | if($ConfigNewUser) 252 | { 253 | ########################## 254 | ## Add a new user 255 | ########################## 256 | # Create new user account if it does not exist 257 | $passwordSec = ConvertTo-SecureString -String $password -AsPlainText -Force 258 | 259 | $account = Get-LocalUser -Name $username -ErrorAction SilentlyContinue 260 | if (-not ($null -eq $account)) { 261 | Log-Message ("The User "+$username+" already exists. The User will be reseted.") 262 | $User_Old_SID=Get-UsernameSID($username) 263 | $Global:ShellLauncherClass.RemoveCustomShell($User_Old_SID) 264 | Remove-LocalUser -Name $username 265 | } 266 | $newUser=New-LocalUser -Name $username -FullName $username -Description "Standard Windows user for custom shell" -Password $passwordSec 267 | if ($null -eq $newUser) { 268 | 269 | Log-Message ("The user "+$username+" cannot be created") 270 | exit 271 | } 272 | Set-LocalUser $username -PasswordNeverExpires $TRUE 273 | Log-Message ("The User "+$username+" was created succesfully") 274 | # Make the user part of the User group 275 | $groupSID = "S-1-5-32-545" #SID of the Users Group 276 | Add-LocalGroupMember -SID $groupSID -Member $username 277 | 278 | 279 | 280 | ################################## 281 | ## Enable Autologon for the Shell-User 282 | ################################## 283 | 284 | $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" 285 | 286 | Set-ItemProperty $RegPath "AutoAdminLogon" -Value "1" -type String 287 | Set-ItemProperty $RegPath "DefaultUsername" -Value "$username" -type String 288 | Set-ItemProperty $RegPath "DefaultPassword" -Value "$password" -type String 289 | Log-Message ("Auto Login for the User "+$username+" is enabled") 290 | 291 | ############################ 292 | } 293 | 294 | # Check if shell launcher license is enabled 295 | 296 | 297 | [bool]$result = $FALSE 298 | 299 | $result = Check-ShellLauncherLicenseEnabled 300 | "`nShell Launcher license enabled is set to " + $result 301 | if (-not($result)) 302 | { 303 | "`nThis device doesn't have required license to use Shell Launcher" 304 | exit 305 | } 306 | 307 | 308 | 309 | 310 | # This security identifier (SID) responds to the BUILTIN\Administrators group 311 | 312 | $Admins_SID = "S-1-5-32-544" 313 | 314 | 315 | # Get the SID for a user account. Rename "Operator" to an existing account on your system to test this script 316 | 317 | $Operator_SID = Get-UsernameSID($username) 318 | 319 | 320 | $Global:ShellLauncherClass.SetDefaultShell("cmd.exe", $Shell_Launcher_Exit_Action) 321 | 322 | # Display the default shell to verify that it was added correctly 323 | 324 | $DefaultShellObject = $Global:ShellLauncherClass.GetDefaultShell() 325 | 326 | Log-Message ("Default Shell is set to " + $DefaultShellObject.Shell + " and the default action is set to " + $DefaultShellObject.defaultaction) 327 | 328 | # Set Edge as the shell for "Operator", and restart the machine if Edge is closed 329 | 330 | 331 | $ExistingShell =$Global:ShellLauncherClass.GetCustomShell($Operator_SID) 332 | if (-not ($null -eq $ExistingShell)) { 333 | Log-Message("The Custom-Sehll for the User with SID "+$Operator_SID+" was removed") 334 | $Global:ShellLauncherClass.RemoveCustomShell($Operator_SID) 335 | } 336 | 337 | $Global:ShellLauncherClass.SetCustomShell($Operator_SID, $customShellApp, ($null), ($null), $Shell_Launcher_Exit_Action) 338 | 339 | # Set Explorer as the shell for administrators 340 | $ExistingShell =$Global:ShellLauncherClass.GetCustomShell($Admins_SID) 341 | if (-not ($null -eq $ExistingShell)) { 342 | Log-Message("The Custom-Sehll for the User with SID "+$Admins_SID+" was removed") 343 | $Global:ShellLauncherClass.RemoveCustomShell($Admins_SID) 344 | } 345 | $Global:ShellLauncherClass.SetCustomShell($Admins_SID, "explorer.exe") 346 | 347 | # View all the custom shells defined 348 | $C=Get-WmiObject -class WESL_UserSetting @CommonParams | Select Sid, Shell, DefaultAction 349 | Log-Message ("Current settings for custom shells: "+ (Out-String -InputObject $C -Width 350)) 350 | 351 | # Enable Shell Launcher 352 | 353 | $Global:ShellLauncherClass.SetEnabled($TRUE) 354 | 355 | $IsShellLauncherEnabled = $Global:ShellLauncherClass.IsEnabled() 356 | 357 | Log-Message ("Shell Launcher Status is set to " + $IsShellLauncherEnabled.Enabled) 358 | 359 | } 360 | function Enable-Predefined-Key($Id) 361 | { 362 | $predefined = Get-WMIObject -class WEKF_PredefinedKey @CommonParams | 363 | where { 364 | $_.Id -eq "$Id" 365 | }; 366 | 367 | if ($predefined) 368 | { 369 | $predefined.Enabled = 1; 370 | $predefined.Put() | Out-Null; 371 | } 372 | else 373 | { 374 | 375 | Log-Message ("$Id is not a valid predefined key") 376 | } 377 | } 378 | function Get-Setting([String] $Name) { 379 | <# 380 | .Synopsis 381 | Get a WMIObject by name from WEKF_Settings 382 | .Parameter Name 383 | The name of the setting, which is the key for the WEKF_Settings class. 384 | #> 385 | $Entry = Get-WMIObject -class WEKF_Settings @CommonParams | 386 | where { 387 | $_.Name -eq $Name 388 | } 389 | 390 | return $Entry 391 | } 392 | 393 | function Set-DisableKeyboardFilterForAdministrators([Bool] $Value) { 394 | <# 395 | .Synopsis 396 | Set the DisableKeyboardFilterForAdministrators setting to true or 397 | false. 398 | .Description 399 | Set DisableKeyboardFilterForAdministrators to true or false based 400 | on $Value 401 | .Parameter Value 402 | A Boolean value 403 | #> 404 | 405 | $Setting = Get-Setting("DisableKeyboardFilterForAdministrators") 406 | if ($Setting) { 407 | if ($Value) { 408 | $Setting.Value = "true" 409 | } else { 410 | $Setting.Value = "false" 411 | } 412 | $Setting.Put() | Out-Null; 413 | } else { 414 | 415 | Log-Message ("Unable to find DisableKeyboardFilterForAdministrators setting") 416 | } 417 | } 418 | 419 | function Set-BreakoutMode($Value) { 420 | 421 | 422 | $Setting = Get-Setting("BreakoutKeyScanCode") 423 | if ($Setting) { 424 | 425 | $Setting.Value = $Value 426 | $Setting.Put() | Out-Null; 427 | Log-Message ("Configure the scan code "+$Value+" as Breakout Key") 428 | } else { 429 | 430 | Log-Message ("Unable to find BreakoutKeyScanCode setting") 431 | } 432 | } 433 | 434 | function Configure-KeyboardFilter 435 | { 436 | Set-Service -Name MsKeyboardFilter -StartupType Automatic -Status Running -PassThru 437 | # Disable keyboard filter for Administrator account 438 | Set-DisableKeyboardFilterForAdministrators $DisableKeyboardFilterForAdministrator 439 | #Configure the Breakout Key 440 | Set-BreakoutMode $BreakoutKey 441 | 442 | # Enable filters 443 | # Key combinaitons listed below will not be actioned 444 | Get-WMIObject -class WEKF_Settings @CommonParams -ErrorAction Stop 445 | foreach($i in $FilteredKeys) 446 | { 447 | Enable-Predefined-Key $i 448 | } 449 | Log-Message ("Enabled Predefined Keys") 450 | Get-WMIObject -class WEKF_PredefinedKey @CommonParams | 451 | foreach { 452 | if ($_.Enabled) { 453 | write-host $_.Id 454 | Log-Message ($_.Id) 455 | } 456 | } 457 | 458 | Log-Message ("Enabled Custom Keys") 459 | Get-WMIObject -class WEKF_CustomKey @CommonParams | 460 | foreach { 461 | if ($_.Enabled) { 462 | write-host $_.Id 463 | Log-Message ($_.Id) 464 | } 465 | } 466 | 467 | Log-Message ("Enabled Scancodes") 468 | Get-WMIObject -class WEKF_Scancode @CommonParams | 469 | foreach { 470 | if ($_.Enabled) { 471 | "{0}+{1:X4}" -f $_.Modifiers, $_.Scancode 472 | } 473 | } 474 | 475 | } 476 | 477 | function Configure-UnbrandedBoot 478 | { 479 | # To disable the F8 key during startup to prevent access to the advanced startup options menu 480 | cmd /c "bcdedit.exe -set {globalsettings} advancedoptions false" 481 | 482 | # To disable the F10 key during startup to prevent access to the advanced startup options menu 483 | cmd /c "bcdedit.exe -set {globalsettings} optionsedit false" 484 | 485 | # To suppress all Windows UI elements (logo, status indicator, and status message) during startup 486 | cmd /c "bcdedit.exe -set {globalsettings} bootuxdisabled on" 487 | 488 | # To disable automatic repair console during startup 489 | cmd /c "bcdedit.exe -set {current} recoveryenabled NO" 490 | 491 | # To disable bootstatuspolicy at startup 492 | cmd /c "bcdedit.exe -set {current} bootstatuspolicy ignoreallfailures" 493 | } 494 | 495 | function Configure-CustomLogon 496 | { 497 | if ($BrandingNeutral -eq $TRUE) 498 | { 499 | Set-Itemproperty -path 'HKLM:\SOFTWARE\Microsoft\Windows Embedded\EmbeddedLogon' -Name 'BrandingNeutral' -value '00000001' 500 | } 501 | else { 502 | Set-Itemproperty -path 'HKLM:\SOFTWARE\Microsoft\Windows Embedded\EmbeddedLogon' -Name 'BrandingNeutral' -value '00000000' 503 | } 504 | 505 | if ($HideAutoLogonUI -eq $TRUE) 506 | { 507 | Set-Itemproperty -path 'HKLM:\SOFTWARE\Microsoft\Windows Embedded\EmbeddedLogon' -Name 'HideAutoLogonUI' -value '00000001' 508 | } 509 | else { 510 | Set-Itemproperty -path 'HKLM:\SOFTWARE\Microsoft\Windows Embedded\EmbeddedLogon' -Name 'HideAutoLogonUI' -value '00000000' 511 | } 512 | 513 | Set-Itemproperty -path 'HKLM:\SOFTWARE\Microsoft\Windows Embedded\EmbeddedLogon' -Name 'HideFirstLogonAnimation' -value '00000001' 514 | } 515 | ##########-----------The script starts here---------################## 516 | 517 | Log-Message("---------------------------------------") 518 | Enable-LockdownFeatures 519 | 520 | if($ConfigureShellLauncher -eq $TRUE) 521 | { 522 | Configure-ShellLauncher 523 | } 524 | 525 | if($ConfigureKeyboardFilter -eq $TRUE) 526 | { 527 | Configure-KeyboardFilter 528 | } 529 | 530 | if($ConfigureUnbrandedBoot -eq $TRUE) 531 | { 532 | Configure-UnbrandedBoot 533 | } 534 | 535 | if($ConfigureCustomLogon -eq $TRUE) 536 | { 537 | Configure-CustomLogon 538 | } 539 | 540 | 541 | 542 | 543 | 544 | --------------------------------------------------------------------------------