Tag: Remoting

PowerShell Direct Enter-PSSession

Hyper-V PowerShell Direct

One of the new features of Hyper-V in Windows Server 2016 and Windows 10 is called PowerShell Direct. PowerShell Direct lets you remotely connect to a Virtual Machine running on a Hyper-V host, without any network connection inside the Virtual Machine. PowerShell Direct uses the Hyper-V VMBus to connect inside the Virtual Machine. This feature is convenient if you need it for automation and configuration for Virtual Machines or if you for example messed up network configuration inside the virtual machine and you don’t have console access.

Right now, there are two ways to use PowerShell Direct:

  • Create and exit a PowerShell Direct session using PSSession cmdlets
  • Run script or command with the Invoke-Command cmdlet
  • Use the PowerShell Direct session to copy files using the copy-item cmdlet

Requirements:

  • The virtual machine must be running locally on the Hyper-V host and must be started.
  • You must be logged into the host computer as a Hyper-V administrator.
  • You must supply valid user credentials for the virtual machine.
  • The host operating system must run Windows 10, Windows Server 2016, or a higher version.
  • The virtual machine must run Windows 10, Windows Server 2016, or a higher version.

PowerShell Direct examples

You can open a new interactive PowerShell Direct Session:

PowerShell Direct Enter-PSSession

Enter-PSSession -VMName "VM01" -Credential (Get-Credential)

PowerShell Direct Invoke-Command

You can use Invoke-Command to send script blocks to your Hyper-V Virtual Machines.

Invoke-Command -VMName "VM01" -Credential (Get-Credential) -ScriptBlock { Get-Process }

You can also create a PowerShell Direct session and use the Copy-Item -ToSession cmdlet to copy files to or from the VM.

$s = New-PSSession -VMName "VM01" -Credential (Get-Credential)
Copy-Item C:\Files C:\Targetfiles -ToSession $s

Remember it, this is not the same as PowerShell Remoting, even if it uses the same cmdlets. With that, not everything is working using PowerShell Direct, for some scenarios, PowerShell Remoting works differently. If you want to do this with Linux virtual machines, there is a tool called hvc.exe, which allows you to do the same.

If you want to know more about PowerShell Direct, check out the Microsoft Docs pages.



Windows 10 IoT PowerShell Cred

How to connect to Windows 10 IoT Core via PowerShell

After you have done the setup of your Raspberry Pi 2 with Windows 10 IoT Core you can now connected to the device via PowerShell.

Connect to the Windows 10 IoT device using PowerShell

First open up PowerShell and configure PowerShell remoting to allow your PC to remotely connect to your Raspberry Pi 2. You can use the name of your Raspberry Pi, which is “minwinpc” by default, or you can also using the IP address. You can also use the Windows 10 IoT Core Watcher which helps you find your devices on the network.

 
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "machine-name or IP Address"

You can now open a new PowerShell Remote session by using the following command:

 
Enter-PsSession -ComputerName "machine-name or IP Address" -Credential "machine-name or IP Address or localhost"\Administrator

Windows 10 IoT PowerShell Cred

This will prompt you for credentials. The default password of your Pi is “[email protected]

You can also store the credentials inside a variable, so you do not have to enter it all the time:

 
$Cred = Get-Credential
Enter-PsSession -ComputerName "machine-name or IP Address" -Credential $Cred

Windows 10 IoT PowerShell Remoting minwinpc

To create the connection this can take up to 30 seconds. After that you will see the remote session.

Using PowerShell on your Windows 10 IoT Core device

You can now use PowerShell to do some stuff on your Raspberry Pi with Windows 10 IoT Core. Some PowerShell commands are not build in to Windows 10 IoT Core but you can use some command line utilities.

Get all the process running:

 
Get-Process

Windows 10 IoT PowerShell Processes

Get network adapter configuration:

 
Get-NetAdapter

List the directories:

 
gci

Rename your computer:

By renaming your device, you have to reconnect and may change your credentials.

 
setcomputername "newcomputername"

Change the password of your administrator:

 
net user Administrator <newpassword>

Shutdown your device

 
shutdown /s /t 0

Windows 10 IoT PowerShell Shutdown

Reboot your device

 
shutdown /r /t 0

Close your remote session

 
Exit-PSSession

I hope this helps you to manage your Windows 10 IoT Core device via PowerShell.



Automated Active Directory Deployment with PowerShell

Powershell

For a small presentation at KTSI I created a PowerShell script will automatically will deploys Active Directory Servers, adds other member servers, creates Organization Units and adds users via Powershell Remoting. As source there is a XML configuration file and CSV files for User Data.

Install AD with Powershell

This script is just for Lab deployments not for production, and it is not perfect, but I think maybe some people will enhance this script with their own code.

I do not support this script. it is just something I need to deploy my test environments and nothing more. More it shows diffrent

You can find more information about it works in this document.

XML Config file:

 
<?xml version="1.0" encoding="utf-8"?>
<lab>
<config>
<servers>
<server name="ADS01" ip="192.168.100.11" id="1" adminpw="passw0rd"/>
<server name="ADS02" ip="192.168.100.12" id="2" adminpw="passw0rd"/>
</servers>
<ad>
<domain name="ktsi.local" netbiosname="ktsi" forestlevel="4" domainlevel="4" safemodepw="passw0rd" />
</ad>
<ous>
<ou name="UserAccounts" path="DC=KTSI,DC=LOCAL" />
<ou name="BASEL" path="OU=USERACCOUNTS,DC=KTSI,DC=LOCAL" />
<ou name="CHICAGO" path="OU=USERACCOUNTS,DC=KTSI,DC=LOCAL" />
<ou name="NEWYORK" path="OU=USERACCOUNTS,DC=KTSI,DC=LOCAL" />
<ou name="SALES" path="OU=BASEL,OU=USERACCOUNTS,DC=KTSI,DC=LOCAL" />
<ou name="IT" path="OU=BASEL,OU=USERACCOUNTS,DC=KTSI,DC=LOCAL" />
<ou name="ADMINISTRATION" path="OU=BASEL,OU=USERACCOUNTS,DC=KTSI,DC=LOCAL" />
<ou name="PRODUCTION" path="OU=BASEL,OU=USERACCOUNTS,DC=KTSI,DC=LOCAL" />
<ou name="SALES" path="OU=CHICAGO,OU=USERACCOUNTS,DC=KTSI,DC=LOCAL" />
<ou name="IT" path="OU=CHICAGO,OU=USERACCOUNTS,DC=KTSI,DC=LOCAL" />
<ou name="ADMINISTRATION" path="OU=CHICAGO,OU=USERACCOUNTS,DC=KTSI,DC=LOCAL" />
<ou name="PRODUCTION" path="OU=CHICAGO,OU=USERACCOUNTS,DC=KTSI,DC=LOCAL" />
<ou name="SALES" path="OU=NEWYORK,OU=USERACCOUNTS,DC=KTSI,DC=LOCAL" />
<ou name="IT" path="OU=NEWYORK,OU=USERACCOUNTS,DC=KTSI,DC=LOCAL" />
<ou name="ADMINISTRATION" path="OU=NEWYORK,OU=USERACCOUNTS,DC=KTSI,DC=LOCAL" />
<ou name="PRODUCTION" path="OU=NEWYORK,OU=USERACCOUNTS,DC=KTSI,DC=LOCAL" />
</ous>
<users>
<file name="users.csv" path="OU=ADMINISTRATION,OU=BASEL,OU=USERACCOUNTS,DC=KTSI,DC=LOCAL" />
</users>
<members>
<member name="PC101" ip="192.168.100.21" />
<member name="PC101" ip="192.168.100.22" />
<member name="PC101" ip="192.168.100.23" />
</members>
</config>
</lab>

The PowerShell Script:



Powershell: Convert String to Scriptblock

If you use PowerShell remoting in some scripts, you will ses you cannot use a string to send it with the Invoke-Command cmdlet.

So you can simple convert a String to a Scriptblock

 $scriptBlock = [Scriptblock]::Create($string)

Now here an example

$remoteCommand =
@"
Import-Module ActiveDirectory
New-ADOrganizationalUnit -name
"@
 
$scriptBlock = [Scriptblock]::Create($remoteCommand)
 
Invoke-Command -ComputerName AD01 -ScriptBlock $scriptBlock

Basically you could create a function for that.

function ConvertTo-Scriptblock {
<# Function to Convert a String into a Script Block #>
Param(
[Parameter(
Mandatory = $true,
ParameterSetName = '',
ValueFromPipeline = $true)]
[string]$string
)
$scriptBlock = [scriptblock]::Create($string)
return $scriptBlock
}


Quick Powershell Remoting Guide

Powershell HeaderThis is small guide which allows you to create Remote Powershell Sessions (like SSH). It allows you to create connection to Host which have Powershell Version 2.

  • Allow Powershell Remoting on the Remotehost
  • Add Trusted Hosts on the Localcomputer
  • Create a new Remotesession
  • Leave a Powershell Remotesession
  • Close a Powershell Remotesession
  • Send a command to a Remotehost

Allow Powershell Remoting on the Remotehost

Run Powershell 2.0 on the Remotehost and run the following Cmdlet.

Enable-PSRemoting

This command starts the WinRM service if it’s not allready started and sets the startup type to automatic. Adds firewall exceptions for WS-Management communications and creates a listener to accept requests.

Add Trusted Hosts on the Localcomputer

On the Local Computer run Powershell and run the following Cmdlet. This allows you to connect to any host. It also starts WinRM if its not already started.

Set-Item WSMan:\localhost\Client\TrustedHosts *

After that you may have to restart the WinRM service

Restart-Service winrm -Force

Create a new Powershell Remotesession

There are two ways to create a new PS Remotesession.

New-PSSession -ComputerName Server01

With Get-PSSession you can list all active sessions. Now you can enter a active Session with Enter-PSSession and the ID

Enter-PSSession 2

A quicker way to do that, you can simply use Enter-PSSession to create a new Session and directly connect to this Session.

Enter-PSSession -ComputerName Server02

Leave a Powershell Remotesession

To leave a Powershell Remotesession you can simply use the Exit-PSSession

Exit-PSSession

Close a Powershell Remotesession

To close a Powershell Remotesession you can list all  active Sessions with Get-PSSessions and close them with Remove-PSSession.

Get-PSSession | Remove-PSSession

Send a command to a Remotehost

To run a command on a Remotehost you can use the -ComputerName parameter.

Get-Service -ComputerName Server02
Get-Service -ComputerName Server02 | Where-Object {$_.Name -eq "BITS"}

With this little snippet you can run commands on multiple Hosts

 
$Servers = @("Server01", "Server02")
 
foreach ($Server in $Servers) {
 
Write-Host "Server: " $server
 
Get-Service -ComputerName $server | Where-Object {$_.Name -eq "BITS"}
 
}