Close

Experimental:Windows Powershell and TouchDesigner

What is PowerShell

PowerShell is a cross platform task-based command-line shell and scripting language designed with a focus on system administration. It is the most modern command shell designed directly into Windows and can function as a replacement to the Windows CMD shell as well as ported linux / unix variants like MINGW64 that comes with GIT etc. The shell supports Windows commands and many familiar Unix commands. It operates well to translate the annoying differences between path and string manipulations between Unix and Windows. It functions well with Python and shares a great deal of similarities with Python. It provides easy access to WMI and .NET and is well integrated into the WSMAN architecture of Windows providing direct access to drivers and other system instrumentation as well as tools to manage Windows security. All these factors and more make PowerShell a useful tool for TouchDesigner engineers who deploy computer clusters from private networks to the cloud. This document covers how to setup PowerShell and Windows Security Policy to simplify management of TouchDesigner applications running over a network. For more general information on PowerShell start here...

https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/powershell

Security Warning!!

This document does not cover making your computers safe from intrusion via the Internet or other nefarious networks. Windows and Internet security is your organization's responsibility and the recommendations in this article will have to be evaluated against the risks, policies and circumstances of your own network environment. In particular this document focuses on the use of CredSSP and RDP as a solution for remotely controlling Windows clients running TouchDesigner graphics applications. Some network administrators and network situations will not permit these technologies to run as they present more avenues for attack, particularly on cloud and Internet adjacent networks. These dangers are to be expected as what we are discussing is ubiquitous control of TouchDesigner over a cluster of computers. With great power comes great responsibility.

Alternative Technologies for Remote Control of Computers

There are other technologies for remotely controlling computers that have different security implications which may fit better for your needs. In particular, there has been some success in the community using MQTT protocol and Node Red.

Here is a video of Elburz talking about Node Red: https://www.youtube.com/watch?v=V96AxxRNLLA

Setting up PowerShell

The following section covers how to configure Windows 10 computers for remote control using Powershell.

https://gist.github.com/jarrettgsmith/8d5b467cd3a3b6d6d547eeebebe4ba1e

User Account Setup Checklist

  • All computers should be assigned a common user that matches in name and password for each system.
  • This user account must have Administrative privileges.

Opening PowerShell in Administrator Mode

Open PowerShell by clicking the Windows Start menu and instantly search by typing "PowerShell". The PowerShell icon will appear in the Start menu. You must start the PowerShell in Administrative Mode. To do so, right click on the icon and from the popup menu select "Run as Administrator". Alternatively, right click on the Start menu and select "Windows Powershell (Admin)". When starting PowerShell in Administrator mode, you may get a Windows dialog popup notification, which you should click Yes to. When open the PowerShell application window header will read "Administrator: Windows PowerShell"

Activate Windows Remote Management Service (WinRM)

You must ensure Windows Remote Management (WinRM) service is running and also that it will automatically start when you restart Windows. PowerShell provides an easy command to make this process simple.

  • Verify your username and computername to make sure you are working in the shell as the correct user and on the correct computer. The username returned here is the username you should be using in PowerShell. It may not match what username appears at the Windows login screen, which for example might be an email address.
$env:UserName
$env:ComputerName
  • Run the WinRM quick configuration command to setup remote services and general remote configuration...

winrm quickconfig

  • If things are already setup correctly you will get this...

WinRM service is already running on this machine.
WinRM is already set up for remote management on this computer.
  • If things are not setup yet you will proceed through the questions...
WinRM is not set up to receive requests on this machine.
The following changes must be made:
Start the WinRM service.
Set the WinRM service type to delayed auto start.
  • Type "y" for this and every requirement that follows. It will set some permissions rules and a firewall exception.
  • Run the following PowerShell commands to setup the firewall for clear communication between hosts.
netsh advfirewall firewall add rule name="Enable Echo Ping Request" protocol="icmpv4:8,any" dir=in action=allow
netsh advfirewall firewall set rule group="File and Printer Sharing" new enable=Yes
  • Setup trusted hosts to trust all computer names. # Trust all hosts
Set-Item WSMan:localhost\client\trustedhosts -value *
  • Verify trusted hosts configuration
Get-Item WSMan:\localhost\Client\TrustedHosts
  • Repeat these steps for each computer you want to control remotely on the network.
  • Double check your permissions on each computer. From each system, you should be able to open a PowerShell and ping every other system.

Testing PowerShell

If things are configured correctly you should be able to do the following.

  • Log into any other configured host with the following command.
Enter-PSSession -ComputerName <COMPUTERNAME> -Credential <USERNAME>
  • A Windows dialog for PowerShell credentials will appear. Enter your password here. Once logged in, you will notice the command prompt indicates you are logged into another host by printing the computer name between square brackets at the start of the command line [COMPUTERNAME]. For example the regular administrator prompt looks like this...
PS C:\Windows\System32>
  • While the prompt looks something like this when logged into the remote host.
[ComputerName]: PS C:\Users\UserName\Documents>
  • When logged into another host with a remote shell you can run any command using the Invoke-Command.
[ComputerName]: PS C:\Users\UserName\Documents> Invoke-Command -scriptblock {$env:ComputerName}
  • Or when on your local shell prompt you can run any command remotely using Invoke-Command with credentials.
PS C:\Windows\System32> Invoke-Command -ComputerName COMPUTERNAME -Credential USERNAME -scriptblock {$env:ComputerName}

Understanding Windows Sessions and Powershell

A Windows session consists of all the process and other system objects that represent a single user's logon. When Windows starts up it will start a session that consists of the main services and drivers. As it continues to load into the graphical desktop it loads another session.

Windows PowerShell ISE

Windows PowerShell ISE is a useful interactive tool for experimenting with PowerShell scripts. You can easily sketch ideas and execute them and quickly store and recall your work.

https://docs.microsoft.com/en-us/powershell/scripting/windows-powershell/ise/exploring-the-windows-powershell-ise?view=powershell-7.1

Running TouchDesigner Remotely with PowerShell and PSTools

  • Using the Invoke-Command cmdlet you can execute any application on your local computer. For example to start Notepad open a new PowerShell and use the following command:
Invoke-Command -scriptblock {notepad}
  • However running the same command from a remote PSSession will start the application but the user interface will never appear. Checking the Windows Task Manager will reveal that Notepad started but Windows security does not permit graphical applications to open from remote sessions. There are two know methods to work around this issue. The first is to install PSTools and the second is to use the Windows Task Scheduler.

Installing PSTools

  • PSTools is a set of shell executable commands that facilitate the automation of computer behavior - in particular starting and stopping applications as well as Windows services and other nice features. These are tools provided by Microsoft. They don't need to be installed with an installer, simply unzip them to a location in the Windows application path. A recommended location that is automatically in the Windows application path is C:\Users\<MYUSERFOLDER>\AppData\Local\Microsoft\WindowsApps .
  • Download PsTools Suite here...
https://docs.microsoft.com/en-us/sysinternals/downloads/pstools

$s = New-PSSession -ComputerName HOSTNAME -Credential USERNAME

Copy-Item -ToSession $s C:\PowerShellZipFolder\ps*.exe -Destination C:\Users\USERNAME\AppData\Local\Microsoft\WindowsApps\ -PassThru

Starting Applications with PSExec

Enter-PSession

Enter-PSSession -ComputerName HOSTNAME -Credential USERNAME

psexec \\localhost -i -d -u "NT AUTHORITY\NETWORK SERVICE" notepad

Stop-Process -Force -Name "notepad"

Exit-PSession

New-PSession

$s = New-PSSession -ComputerName HOSTNAME -Credential USERNAME

Enter-PSession $s

psexec \\localhost -i -d -u "NT AUTHORITY\NETWORK SERVICE" notepad

Stop-Process -Force -Name "notepad"

Exit-PSession $s

Start Stop Notepad

Invoke-Command –ComputerName HOSTNAME -Credential USERNAME -ScriptBlock {psexec -accepteula -s \\localhost -i -d -u "NT AUTHORITY\NETWORK SERVICE" notepad}

Invoke-Command –ComputerName HOSTNAME -Credential USERNAME -ScriptBlock {Stop-Process -Force -Name "notepad"}

Executing Powershell Scripts

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-7.1

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine

Get-ExecutionPolicy -List

PowerShell Cheatsheet

  • Invoke-Command -ScriptBlock {notepad}
  • Invoke-Command –ComputerName HOSTNAME -Credential USERNAME -ScriptBlock {psexec -s \\localhost -i -d -u "NT AUTHORITY\NETWORK SERVICE" notepad}

Check the status of WinRM

  • Get-WmiObject -Class win32_service | Where-Object {$_.name -like "WinRM"}
  • Disconnect-PSSession -Id (1..5)
  • Get-PSSession | Disconnect-PSSession | Remove-PSSession: