├── 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 |
--------------------------------------------------------------------------------