Announcing ‘Tomte’: The Customisable Remote Administration Tool for Windows Systems

TL;DR – I’ve released source code for remote systems administration via PowerShell + WCF + WindowsService, here, under the Mozilla Public License 2.0. 

Windows has a huge, glaring gap where Linux really shines: Remote configuration via tools. Sure, there’s DSC (Desired State Configuration) but it doesn’t help much for run-time automation and administration.

Tomte (o, as in phone, and ‘e’, as in meh) is a framework (though lacking in some features) that was written to primarily address that and give SRE/DevOps teams a tool to quickly add an activity to be used (just add a PowerShell command and then the corresponding activity).

First things, first: We have to set the SQL Server up. Install your flavour of SQL server (I’ve port this code twice, now, so I just kept the instance name, as that made life easier) and run the following commands from the command line, replacing the instance name with your SQL Server instance and the database name with the database that you created.

osql -E -S .\SQL2008Express -d WorkflowInstanceStore -i C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SQL\en\SqlWorkflowInstanceStoreSchema.sql

osql -E -S .\SQL2008Express -d WorkflowInstanceStore -i C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SQL\en\SqlWorkflowInstanceStoreLogic.sql

IMPORTANT: If you want to configure the service to use a user-account, please change that in the source code and add permissions for the account to the SQL database; otherwise, the SQL database will require Anonymous Logon permissions, as the Local System account used for the Windows Service is obfuscated as an anonymous logon on SQL Server.

Now that the database is set-up, you’ll need to punch a hole in your firewall to listen on port 65534. You can change the listen port in the application configuration file of the Windows Service (Felsökning.Tomte.AdminService) via the baseAddress setting.

        <host>

<baseAddresses>

<!– NOTE: The ‘*’ allows the service to install on any given machine –>

<add baseAddress=”http://*:65534/WorkflowService/service”/>

</baseAddresses>

</host>

Now that we have the SQL database ready and we’ve punched a hole in the firewall, we should install the Windows Service, first. Ensure that the build configuration of all of the projects is set to ‘x64’ and clean/build the solution.

To install the windows service, we’ll leverage the standard tools that ship with .NET, to prevent any cursory problems with “specialised” versions of these tools. In an elevated command (or PowerShell) window, run the following to install the service, replacing the path with your build’s output path.

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe C:\Code\git\felsokning\Tomte\Felsökning.Tomte\Felsökning.Tomte.AdminService\bin\x64\Debug\Felsökning.Tomte.AdminService.exe

Installationsverktyg för Microsoft (R) .NET Framework, version 4.7.3190.0

Copyright (C) Microsoft Corporation. Med ensamrätt.

 

 

Kör en överförd installation.

 

Startar installationsfasen av installationen.

Se loggfilen om du vill ha information om installationsförloppet för sammansättningen C:\Code\git\felsokning\Tomte\Felsökning.Tomte\Felsökning.Tomte.AdminService\bin\x64\Debug\Felsökning.Tomte.AdminService.exe.

Filen finns på C:\Code\git\felsokning\Tomte\Felsökning.Tomte\Felsökning.Tomte.AdminService\bin\x64\Debug\Felsökning.Tomte.AdminService.InstallLog.

Installerar sammansättningen C:\Code\git\felsokning\Tomte\Felsökning.Tomte\Felsökning.Tomte.AdminService\bin\x64\Debug\Felsökning.Tomte.AdminService.exe.

Berörda parametrar är:

logtoconsole =

assemblypath = C:\Code\git\felsokning\Tomte\Felsökning.Tomte\Felsökning.Tomte.AdminService\bin\x64\Debug\Felsökning.Tomte.AdminService.exe

logfile = C:\Code\git\felsokning\Tomte\Felsökning.Tomte\Felsökning.Tomte.AdminService\bin\x64\Debug\Felsökning.Tomte.AdminService.InstallLog

Installerar tjänsten Felsökning.Tomte.AdminService…

Tjänsten Felsökning.Tomte.AdminService har installerats.

Skapar EventLog-källan Felsökning.Tomte.AdminService i loggen Application…

 

Installationsfasen slutfördes och allokeringsfasen inleds.

Se loggfilen om du vill ha information om installationsförloppet för sammansättningen C:\Code\git\felsokning\Tomte\Felsökning.Tomte\Felsökning.Tomte.AdminService\bin\x64\Debug\Felsökning.Tomte.AdminService.exe.

Filen finns på C:\Code\git\felsokning\Tomte\Felsökning.Tomte\Felsökning.Tomte.AdminService\bin\x64\Debug\Felsökning.Tomte.AdminService.InstallLog.

Utför sammansättningen C:\Code\git\felsokning\Tomte\Felsökning.Tomte\Felsökning.Tomte.AdminService\bin\x64\Debug\Felsökning.Tomte.AdminService.exe.

Berörda parametrar är:

logtoconsole =

assemblypath = C:\Code\git\felsokning\Tomte\Felsökning.Tomte\Felsökning.Tomte.AdminService\bin\x64\Debug\Felsökning.Tomte.AdminService.exe

logfile = C:\Code\git\felsokning\Tomte\Felsökning.Tomte\Felsökning.Tomte.AdminService\bin\x64\Debug\Felsökning.Tomte.AdminService.InstallLog

 

Allokeringsfasen slutfördes.

 

Den överförda installationen slutfördes.

Now that the Windows Service is installed, we need to start it. You can do this via any number of means. Start>Run>services.msc is an easy way to do that.

With the service running, we can now import the PowerShell module.

Import-Module “C:\Code\git\felsokning\Tomte\Felsökning.Tomte\Felsökning.Tomte.PowerShell\bin\x64\Debug\Felsökning.Tomte.PowerShell.dll” -Verbose

VERBOSE: Loading module from path ‘C:\Code\git\felsokning\Tomte\Felsökning.Tomte\Felsökning.Tomte.PowerShell\bin\x64\Debug\Felsökning.Tomte.PowerShell.dll’.

VERBOSE: Importing cmdlet ‘Update-RemoteWindowsSystem’.

VERBOSE: Importing cmdlet ‘Test-RemotePortConnectivity’.

VERBOSE: Importing cmdlet ‘Test-RemoteFileExists’.

VERBOSE: Importing cmdlet ‘Start-RemoteSecureDelete’.

VERBOSE: Importing cmdlet ‘Set-RemoteComputerName’.

VERBOSE: Importing cmdlet ‘Set-RemoteSymbolServerEnvironmentVariable’.

VERBOSE: Importing cmdlet ‘Restart-RemoteService’.

VERBOSE: Importing cmdlet ‘Restart-RemoteSystem’.

VERBOSE: Importing cmdlet ‘Request-DevOpsElevation’.

VERBOSE: Importing cmdlet ‘Install-RemoteSysInternals’.

VERBOSE: Importing cmdlet ‘Get-RemoteDateTime’.

VERBOSE: Importing cmdlet ‘Get-RemoteFileText’.

VERBOSE: Importing cmdlet ‘Get-RemoteFreeDiskSpace’.

VERBOSE: Importing cmdlet ‘Get-RemoteLoggedOnUsers’.

VERBOSE: Importing cmdlet ‘Get-RemoteOSVersion’.

VERBOSE: Importing cmdlet ‘Get-RemotePingResponse’.

VERBOSE: Importing cmdlet ‘Get-RemoteProcessIds’.

VERBOSE: Importing cmdlet ‘Get-RemoteProcessThreads’.

VERBOSE: Importing cmdlet ‘Get-RemoteServerTimeSkew’.

VERBOSE: Importing cmdlet ‘Get-RemoteSystemUptime’.

VERBOSE: Importing cmdlet ‘Get-RemoteWebResponseString’.

VERBOSE: Importing cmdlet ‘Get-RemoteWindowsEvents’.

VERBOSE: Importing cmdlet ‘Edit-RemoteConfigurationFile’.

VERBOSE: Importing cmdlet ‘Copy-RemoteFiles’.

VERBOSE: Importing cmdlet ‘Copy-RemoteImagesAndLibrariesForProcess’.

Now that the module is loaded, you can run commands against the remote (or local) endpoint running the Windows Service. (As you can see, I’ve found a localisation bug that I need to sort-out with the return from the DateTimeActivity – 05-01-2019 can easily be May 1st or the 5th of January, depending on how you datetime.)

Get-RemoteDateTime -Server 192.168.0.252

den 5 januari 2019 15:00:02

 

Get-RemoteFreeDiskSpace -Server 192.168.0.252

Drive C:\ has 87.52% free

Drive D:\ has 90.22% free

 

Get-RemoteOSVersion -Server 192.168.0.252 -Kernel32

Major  Minor  Build  Revision

—–  —–  —–  ——–

10     0      17763  1

 

Test-RemotePortConnectivity -Server 192.168.0.252 -TargetHost 8.8.8.8 -Port 53

True

Now that we’ve run a few workflows, let’s check the SQL database and verify that the data we expect to find is there.

SQLQuery

SQL Query showing the executions of the Workflows on the machine.

…and that’s just about it.

Hope that this helps someone at some point in the some future. 🙂

2017 Project: Documented Code Samples

NOTE: This post – drafted, composed, written, and published by me – originally appeared on https://blogs.technet.microsoft.com/johnbai and is potentially (c) Microsoft.

In an effort to empower more people across the planet to learn, but for it not to be an arduous journey in doing so, I’ve started heavily commenting code so that people can learn from it. This will be the first of many code ventures that I attempt to do and then share with comments, so that others can learn from it. The reason for the commenting with the links is because I, myself, have often wondered what ‘x’ does or why ‘y’ may have been used; so, in typical learning fashion, I set off to my favourite search engine and undertake to read more on the class, method, property, etc. To save someone the time and heartache of doing that, I include the .NET MSDN/TechNet documentation with the code – to assist self-driven learning.

In this first of series, DownloadBingImage, Wes (Mills) was making a PowerShell script to download the Bing Search Image. Kevin (Miller) asked him if it was in a service or task and Wes replied that it was a task, so I challenged myself to write it into a Windows Service. I rose to the occasion – mostly, out of self-interest in Windows Services, as it would help me to learn more about coding fundamentals in this area.

And, so, a few months of trial and error and I have a working version of the service installed on my local machine and it downloads the image[s]. This same exact code is what I’m sharing with you.

You can find a copy of the code with in-line comments and links to the classes/methods here. If you want to start at the main service entry point, look here.

It should go without saying that I am not a professional developer (albeit, my role does require understanding all aspects of the SDLC), so if you have comments or are confused as to why I did something a particular way (from a professional developer’s perspective) and it doesn’t quite make sense, that’s why: I’m more of a hobbyist than what others would call a “professional”, at this point.

I hope that this helps at least one person on their journey towards software development. If it’s just one, then the effort was worth it. 🙂

Happy Coding!