Uninstall Application with Server Core

There is no way to directly uninstall a program with PowerShell, but you can get there in a PSRemote Session using WMI.  Note, this won’t work for Nano since it doesn’t have WMI.

First you need to open your connection and get the programs with WMI.

Enter-PSSession - ComputerName <YOURCOMPUTER>
$programs = Get-WmiObject -Class win32_product
$programs | Select Name

Now you can see the installed programs.  Find the one you want to remove, counting from zero to get its index in the array.  I want to remove program 5 in my example.  To test, I run a quick command to make sure I have the right entry.


If you get the right program back, proceed to uninstall.


You can rerun the initial commands to make sure it is no longer listed.  When you’re done, make sure to exit your PSRemote session.


Modify DPM Schedule with PowerShell

We recently ran into an issue where we wanted to update the backup schedules for a number of our protection groups.  I did one through the GUI and then decided to write up something in PowerShell.  This script is built to copy the settings from one protection group to another, so you do need to use the GUI once to set it up, or you could use these commands to do that initial change in PowerShell as well.

The odd thing is that you can’t actually copy a schedule from one to the other, so you put the schedule into a variable and pull out the pieces to copy it over.

$PG = Get-DPMProtectionGroup -DPMServerName <YOURDPMSERVER>
for ($i=0;$i -le ($pg.Count-1);$i++) {
Write-Output ('[' + $i.ToString() +'] ' + $pg[$i].Name)
$pgchoice1 = Read-Host -Prompt 'Choose Protection Group to copy schedule FROM'

$sched = Get-DPMPolicySchedule -ProtectionGroup $PG[$pgchoice1] -ShortTerm

for ($i=0;$i -le ($pg.Count-1);$i++) {
Write-Output ('[' + $i.ToString() +'] ' + $pg[$i].Name)
$pgchoice2 = Read-Host -Prompt 'Choose Protection Group to copy schedule TO'

$MPG = Get-DPMModifiableProtectionGroup -ProtectionGroup $PG[$pgchoice2]

Set-DPMPolicySchedule -ProtectionGroup $MPG -Schedule (Get-PolicySchedule $MPG -ShortTerm) -DaysofWeek $sched.WeekDays -TimesOfDay $sched.TimesOfDay

Set-DPMProtectionGroup -ProtectionGroup $MPG

Modify Replica Size with PowerShell

With DPM you may get errors that the DPM is out of disk space for the replica. (ID 58 Details: There is not enough space on the disk (0x80070070))  Assuming you’re not actually out of space, the replica size just needs to be increased.
Unfortunately, the menu option to Modify disk allocation isn’t selectable.
Luckily, we have PowerShell.  NOTE: These scripts assume you’re local to the DPM server, if not you’ll need to add on the -DPMServer switch to the initial commands.
First, we need to get the list of protection groups.  This script block pulls the groups into an array, then outputs their names with the array index.
$pg = Get-DPMProtectionGroup
for ($i=0;$i -le ($pg.Count-1);$i++) {
Write-Output ('[' + $i.ToString() +'] ' + $pg[$i].Name)
Now that you can get the name of the protection group, run the next script block with the index of that entry (in this example, I’m grabbing the second PG, or index 1).  The second bit outputs the datasources in the protection group with their index value in the array and the datasource name.
$ds = Get-DPMDatasource -ProtectionGroup $pg[1]
for ($i=0;$i -le ($pg.Count-1);$i++) {
Write-Output ('[' + $i.ToString() +'] ' + $ds[$i].Name)
Now you can grab the datasource you need to modify.  This script block grabs the individual datasource from the array of datasources, then outputs the name (to make sure you’ve got the right one) and then shows you the current replica size, in GB.
$d = $ds[0]
We can now modify the replica size.  Make sure you update the value for the ReplicaSize switch to match what you need.
Edit-DPMDiskAllocation -Datasource $d -ReplicaSize (24*1024*1024*1024)
Once that completes the Replica should have been resized.  You can use the UI to start a consistency check, but we’re in PowerShell, so let’s just do that here as well.
$cc = Start-DPMDatasourceConsistencyCheck -Datasource $d
Write-Output $cc.Status

VM Switch Team on Windows Server 2016 Nano

So you’ve set up your Nano server to work as a Hyper-V host, and now you’re ready to configure your teamed VM switch.  Except you’re on Nano and have no console to do it, and only two NICs.  What to do?

Well, you can get there, it just takes a little bouncing around.

Configure one of your NICs (make sure to note the MAC address) with an IP on your network so that you can make a connection.  Leave the other NIC unconfigured.

Now you can connected with PowerShell.  You first have to add the IP of the remote Nano server to a Trusted Hosts list for WinRM:

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

Now you can create your remote session:

Enter-PSSession -ComputerName -Credential HostName\Administrator

Now get your network adapters:


If you want to rename them, do that now:

Get-NetAdapter -Name 'Ethernet' | Rename-NetAdapter -NewName Team1
Get-NetAdapter -Name 'Ethernet 1' | Rename-NetAdapter -NewName Team2

Check to see which NIC you’re using now.  I’ll assume that is Team1, so we’re create your VM Switch with just Team2:

New-VMSwitch -Name TeamedvSwitch -NetAdapterName "Team2" -EnableEmbeddedTeaming $true -AllowManagementOS $false

Now check that the team was created correctly:


Now you can add a management NIC and configure it (replace values as necessary for your environment):

Add-VMNetworkAdapter -ManagementOS -Name "Management" -SwitchName "TeamedvSwitch"
Set-VMNetworkAdapterVlan -ManagementOS -VMNetworkAdapterName "Management" -Access -VlanId 2
New-NetIPAddress –InterfaceAlias "vEthernet (Management)" –IPAddress –PrefixLength 24 -DefaultGateway
Set-DnsClientServerAddress -InterfaceAlias "vEthernet (Management)" -ServerAddresses,

Now you need to exit your remote session:

Then set up a rule to allow a connection to the new Team:
Set-Item WSMan:\localhost\Client\TrustedHosts -Value
Now you can connect to the server on the new connection:
Enter-PSSession -ComputerName -Credential HostName\Administrator
Now you just need to add the Team1 NIC into the team:
Set-VMSwitchTeam -Name TeamedvSwitch -NetAdapterName "Team1","Team2"
Now your team is set up and you’re ready to start setting up the rest of your server.  Don’t forget to close out your session when you’re done.

PowerShell Code Signing (2/2)

Now that we’ve completed step 1 and created a certificate, we can proceed to sign some code.

Open a PowerShell session and take a look at your certificates.

dir cert:currentuser\my\

You’ll get a list of your certificates.  If you have a bunch and want to confirm that there is a code signing certificate run:

dir cert:currentuser\my\ | select enhancedusage

to see what they all are or

dir cert:currentuser\my\ -CodeSigningCert

to only see the code signing certs

Store the cert in a variable to make the signing command easier to type.  If you have several code signing certs you will need to reference the one you want to use (with the thumbprint), otherwise we can tell it just to give us the code signing cert.

$cs = dir cert:currentuser\my -CodeSigningCert
$cs = dir cert:currentuser\my\thumbprint

Now you can use the Set-AuthenticodeSignature cmdlet to sign your file.

Set-AuthenticodeSignature -Certificate $cs -FilePath C:\pathtoyourfile.ps1

PowerShell Code Signing (Part 1/2)

Before you can sign your PowerShell code you’ll need to have a code-signing certificate.  If you’re selling your powershell, you’ll want a certificate from a public CA, and there are ways to create your own certificate, but I’ll be focusing on how to do it with an Active Directory Certification Authority.

First, you’ll need to tell your CA that it can issue Code Signing Certificates.  Open the Certification Authority management console, expand to show Certificate Templates.  Then choose New and Certificate Template to Issue.

CertPS1 (1)

Then select the Code Signing template.

CertPS1 (2)

Now close out the Certification Authority console.  Then open an MMC with your certificates.  To do this open an MMC, add the Certificates Snap-In, and choose your user account as the context.

CertPS1 (3)

Once this is open, right-click on your Personal certificate store, choose All Tasks, and Request New Certificate.

CertPS1 (4)

In the certificate request wizard, click next, make sure Active Directory Enrollment is selected, click next, check the box for code signing and then click Enroll.

CertPS1 (5) CertPS1 (6) CertPS1 (7)

You now have a certificate that can be used for PowerShell code signing.