Table of Contents
Now I have been administrating Windows Environments for some years now, and I have been training myself to use Powershell where ever it is possible. I have this dream of being able to come into work, open my terminal, and then do more or less everything from the terminal, and to the most extent, I have been able to do this.
But for a couple of months ago i switched from a Lenovo T14 Windows PC to a Macbook Pro (Intel) 2020. And my personal laptop is a Macbook Pro M1. The reason for the switch i will save for another article.
With the switch i immediately found some problems when administrating Windows Servers , Windows PC’s, Office 365 and Azure. Fortunately with powershell 7 i am able to manage alot of powershell task directly from the Macbook terminal. Actually the only aspect i have not yet been able to crack is Active Directory and Azure Active Directory. It is not possible of my knowledge to use any Windows Powershell active directory commands from powershell 7 to a Windows Domain.
So i created a Virtual Machine and used RDP to connect to the machine and from there i managed to administrate all Active Directory and AAD tasks. But In these time where “Work From Home” is quiet popular it quickly got quiet frustrated dealing with VPN, RDP and slow bandwith. Which made me think if i can create a Windows VM which uses minial resources and then utilize SSH to connect to it, this could be a much better experience. And i was right.
The way it works is than today when i start my Mac i just open a couple of terminal panes as i usually do and in a couple of panes i just ssh to the Windows VM. This way i always have a couple of panes running Windows Powershell.
So for this guide, I have a Windows Server 2019 Core installed on a Hypervisor. This guide can still be followed if you have a VM running on your local machine, and the VM does not have to be Core edition.
Configure the VM to your environments and the needs for your Powershell development / management
So you could utilize this way of interacting with the Windows VM just for Windows Powershell development and testing. In that case, you could just use the VM as a standalone box which you can ssh into.
In my case i need to administrate / develop on Active Directory components. Therefore i will go ahead and do a quick AD Join to my Server
Setup Network Configurations for the Server.
All the configurations on my server I will do with Powershell on the Windows Server 2019 Core, through a RDP connection.
I will domain join my VM, therefore i will give it a Static IP address and point the DNS Server address to my Domain Controller.
Setting the static IPv4 Address:
New-NetIPAddrress -InterfaceAlias "Ethernet" -IPAddress "192.168.40.254" -PrefixLength 24 -DefaultGateway "192.168.40.1" -AddressFamily IPv4
Setting the DNS servers:
Set-DNSClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses "192.168.40.2, 22.214.171.124"
Then i will rename my Virtual Machine and restart it to take effect:
Rename-Computer -NewName ch-ps01 -Restart
Rename-Computer -NewName ch-ps01 -Restart
Then i will domain join the Virtual Machine:
Add-Computer -DomainName "<domain.name>" -DomainCredential "<email@example.com>" -Restart
Set Powershell to be the default Terminal on the Machine
Now for a fresh install of Windows Server Core, the default terminal is CMD. To switch this to be Powershell instead we just need to configure a Registry Key:
Set-ItemProperty -Path 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion\WinLogon' -Name Shell -Value 'PowerShell.exe' Restart-Computer -Force
Now when the machine has restarted you will see that it automatically opens powershell when you login.
Setup the SSH Server
To install the SSH Feature on the Windows Server we can run the following powershell commands:
Fist we need to add the WindowsCapability:
Get-WindowsCapability -Online | ? Name -like 'OpenSSH*' Add-WindowsCapability -Online -Name OpenSSH.Server 0.0.1.0
Once installed you should see the following ouput in your terminal:
Then we need to start the SSH Service and set it to start automatically:
Start-Service sshd Set-Service -Name sshd -StartupType 'Automatic'
Then we need to start the SSH-Agent service and set it to start automatically:
Set-Service -Name SSH-Agent -StartupType 'Automatic' Get-Service -Name SSH-Agent | Start-Service
Then we need to enable a firewall rule to allow access on port 22:
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
Now we can actually try and SSH from the Macbook to our Windows Server.
Because the server is domain joined we will need to provide the domain name in the ssh command. The syntax is as displayed below:
Now if the server wasn’t domain joined the syntax would be:
Creating the SSH Key for connecting to the Windows Server
Now we want to create an SSH Key on the Macbook for accessing the Windows Server. Later on, we will also disable the feature for SSH connecting to the Windows Server with a Username and Password. This will strengthen the security of our VM.
For creating the SSH Key on the Macbook you can run the following command:
ssh-keygen -t rsa
When you are asked where to put the file, just press enter to place the file in the default user location:
Now It will ask for a passphrase, this is strongly recommended to enter. But for LAB/testing purposes you can press enter to not use the SSH key without a passphrase.
Now the SSH Key file has been placed in the folder:
Now the Public key file needs to be copied to the remote server. So we need to transfer the file: id_rsa.pub to the Windows Server. If the user, you are using to login into the windows machine, is part the local group Administrators, then the public key should be placed in the folder:
and the file should be renamed to:
Else if the user is not part of the local group Administrators. Then the file should be placed in the users folder:
and the file should be renamed to:
If the folder C:\Users\\<username>\.ssh\ does not exists, you can just create it yourself.
In my case the user is part of the local group Administrators and i will therefore go with the first solution.
Now one very important thing to know when you copy the file to C:\Users\\\.ssh\ is that only the Administrators Group and SYSTEM has access to that file.
So the easiest way I found to do this is to disable inheritance on the folder, copy the file into the folder, and then remove the user access to the file(Since my user is part of the local administrator’s group, he will still have access to the file.) We are doing this because if the file were open to everyone, then all users could just enter a new key into the file and start ssh remoting into the file.
So i will start disabling inheritance on the folder:
$ACL = Get-Acl -Path C:\ProgramData\ssh\ $ACL.SetAccessRuleProtection($true, $true) $ACL | Set-Acl -Path C:\ProgramData\ssh\
Then i will copy the file from my Mac and onto the Windows VM. To do this i will use SCP
scp ~/.ssh/id_rsa.pub <username>@<domain>.firstname.lastname@example.org:id_rsa.pub
The on the Windows VM i will copy the file into the ssh folder:
Copy-Item -Path C:\Users\<username>\id_rsa.pub -Destination C:\ProgramData\ssh\
Then i will rename the file to the new name administrators_authorized_keys:
Rename-Item C:\ProgramData\ssh\id_rsa.pub -NewName administrators_authorized_keys
Now if we run Get-Acl on the file we can see that the User, Administrators and SYSTEM has access to the file:
(Get-Acl -Path C:\ProgramData\ssh\administrators_authorized_keys).access
we can see that the user also has access to this file. Best practice is to remove this access, since the user already has access through the group Administrators.
To remove the access we can run the follwing:
$ACL = Get-Acl -Path C:\ProgramData\ssh\administrators_authorized_keys $administratorsRule = New-Object system.security.accesscontrol.filesystemaccessrule("Administrators","FullControl","Allow") $systemRule = New-Object system.security.accesscontrol.filesystemaccessrule("SYSTEM","FullControl","Allow") $userRule = New-Object System.Security.AccessControl.FileSystemAccessRule("HOEJSAGER\christian" ,"FullControl","Allow") $ACL.SetAccessRule($administratorsRule) $ACL.SetAccessRule($systemRule) $ACL.RemoveAccessRule($userRule) $ACL | Set-Acl
Now if you run the command Get-Acl you should see the user has been removed from the Access List.
Before we can actually log on to the server using the key, we need to do some configurations on the sshd_config file.
The sshd_config file can be found here: C:\ProgramData\ssh\sshd_config
First we need to uncommnet the line: PubkeyAuthentication Yes
and then change the line: PasswordAuthentication Yes –> to “No”
The save the file and restart the service
Restart-Service -Name sshd
Now you can try and ssh to the Windows VM and, unless you set a passphrase on your key file, you should not be prompted for a password.
If you want the default Terminal, when you ssh to the VM, to be powershell then you can set the following regestry key:
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force
Setting VSCode for SSH remoting
The cool thing about this approach of using ssh and a remote machine for Powershell development is that you can use vscode to remote into the server and develop / test windows Powershell 5.1, directly from your vscode instance running on your Mac.
This setup is incredibly easy to configure. As long as you have done the previous steps and have your Windows VM ready to ssh into.
start by installing the vscode extension “Remote – SSH” on you Mac vscode.
Once installed to start the remote session, press CMD + Shift + P to open the command pallet.
Then write “Remote” to search for the extension.
The press on “Add new SSH Host”
The enter “ssh \<username>@\<domain>.com@windows_vm_ip”
Now you should get connected to your Windows VM.
If you have a passphrase on your Key file the you will be prompted for entering the key.
Now once connected you can navigate through the local file system on the Windows VM, create files, and run Powershell
Finishing touches such as nice to have application on you Windows VM and Creating Alias for SSH command
Now once I install a windows box I usually install a couple of applications to get me going. The same goes for this.
To install the applications I will use the Windows package manager chocolatey. To install chocolatey you can just run the following command:
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
To be sure it installed correct run the following:
Now the applications i will install is the following:
and to do this i just run the following command:
choco install nvim git curl python
Just make sure to press “a” when you are required to and then you should be ready to go.
Then to get the Active Directory Powershell module i will install the RSAT Tools with the following command:
Get-WindowsFeature *RSAT* | Install-WindowsFeature -IncludeAllSubFeature -IncludeManagementTools
After RSAT Tools have been installed the Windows VM is more or less ready to use.
Setting a Alias in the Mac Terminal for easy SSH remoting
The last thing that we will configure is an alias in the Mac terminal. The reason for this is, instead of writing the complete line \<username>@\<domain>.com@windows_vm_ip, you can use an alias such as “gowindows” this is just a quick and easy way to be a bit more effective in the terminal.
Start by opening your .zshrc file found in your home directory.
Go to the end of the file and enter the following:
alias gowindows="ssh <username>@<domain.com>@windows_vm_ip"
The “gowindows” part you can change to whatever makes sense for you.
then save the file and reload it by running:
Now when you write gowindows in the terminal you should get connected to the Windows VM.