Copy windows features from a server to another

Sometimes you want to create the (almost) same server where you do not yet Chef or CF or some sort of DSC. The best resort is to use what you have: get-windowsfeature

Imagine you want to configure Server B from Server A and obviously those are microsoft windows servers…

#On server A
#export features
> Get-WindowsFeature | ? { $_.Installed -AND $_.SubFeatures.Count -eq 0 } | Export-Clixml .\serverA.xml
#copy the feature file over
> cp .\serverA.xml ‘\\serverB\c$\Files’

#On server B
PS C:\Files> ls
Directory: C:\Files
Mode LastWriteTime Length Name
—- ————- —— —-
-a—- 6/8/2017 4:15 PM 510824 ServerA.xml
PS C:\Files> Import-Module Servermanager
PS C:\Files> Import-Clixml .\ServerA.xml | Add-WindowsFeature
Success Restart Needed Exit Code Feature Result
——- ————– ——— ————–
True Yes SuccessRest… {Application Server, .NET Framework 4.5, W…
WARNING: You must restart this server to finish the installation process.

Voila, another posh timesaver.

SCCM2012 (R2) new application creation fails

I had recently migrated my DBs from one volume to another volume due to space concerns, all was successful and life was good ūüôā

However the other day, I wanted to create a new application and got the following “unknown” error.

The SMS Provider reported an error connecting to the ConfigMgr site database server. Verify that the SQL Server is online and that ConfigMgr site server computer account is an administrator on the ConfigMgr site database server.

SmsAdminUI.log would something unknown as well.

Description = “CSspConfigurationItem: SQL_ERROR”;
File = “e:\\qfe\\nts\\sms\\siteserver\\sdk_provider\\smsprov\\sspconfigurationitem.cpp”;
SQLMessage = “*** Unknown SQL Error!”;

Scratched my head a few times and started DDGing as the error was pretty self explanatory and found the following KB/Blog entry.

Basically, after such a DB files location move the SQL TRUSTWORTHY setting gets reset and the dbowner may change.

I hope on the MSSQL and executed the following queries to save the day – well only the creation of new packages.

ALTER DATABASE CM_CIE SET TRUSTWORTHY ON;
EXEC sp_changedbowner ‘sa’;

Then tried to create a new application and voil√†…

Uninstall GP2010 and installation of GP2015

This document describes how to uninstall GP2010 and installation of GP2015.

Prerequisite: local admin rights to uninstall and install software on the machine

  1. Uninstall GP2010 following components
    1. GP2010, Mekorma MICR 2010, Integration Manager for Microsoft Dynamics GP 2010, Dexterity Shared Components 11.0 (64-bit)
    2. Remove the following folders
      1. C:\Program Files (x86)\Microsoft Dynamics\GP2010
      2. C:\Program Files (x86)\Common Files\microsoft shared\Dexterity
  2. Restart the computer
  3. Install GP2015 (includes dexterity 14) as usual.

Uninstall using WMIC

note that Mekorma not playing nice with wmic or msiexec ‚Äď must uninstall manually.

wmic call Msiexec GUID
product where name=‚ÄĚMicrosoft Dynamics GP 2010‚Ä≥ call uninstall /nointeractive {DC90A0A6-2D90-493E-8D13-D54AD123B9FD}
product where name=‚ÄĚIntegration Manager for Microsoft Dynamics GP 2010‚Ä≥ call uninstall /nointeractive {FAFD8B80-E75F-4557-85F3-67B8D7A14E8F}
product where name=‚ÄĚDexterity Shared Components 11.0 (64-bit)‚ÄĚ call uninstall /nointeractive {F5459EB2-A662-4EB3-AD94-E771DC2F542A}
product where name=‚ÄĚMekorma MICR 2010‚Ä≥ call uninstall /nointeractive {A45282DB-59DC-4A5D-9E1F-08A225D81A44}
To run on several nodes at the same time:
wmic:root\cli>/failfast:on /node:@‚ÄĚc:\temp\trainingwks.txt‚ÄĚ product where name=‚ÄĚMicrosoft Dynamics GP 2010‚Ä≥ call uninstall /nointeractive

Managing Certificates using Powershell

Because of my recent work with ADFS I was looking for a way to automate most of the certificate configuration by scripts. The usual run-books I write would usually include the use of the mmc and a bunch of screenshot to accompany them.

The answer is that powershell management for Certificates is there and here are some examples:

 

#Powershell exposes certs under cert:\
PS C:\> Get-PSDrive
Name Used (GB) Free (GB) Provider Root CurrentLocation
—- ——— ——— ——– —- —————
A FileSystem A:\
Alias Alias
C 14.37 45.29 FileSystem C:\
Cert Certificate \
D FileSystem D:\
Env Environment
Function Function
HKCU Registry HKEY_CURRENT_USER
HKLM Registry HKEY_LOCAL_MACHINE
Variable Variable
WSMan WSMan
PS C:\> cd cert:
PS Cert:\> dir localmachine
Name : TrustedPublisher
Name : ClientAuthIssuer
Name : Remote Desktop
Name : Root
Name : TrustedDevices
Name : CA
Name : REQUEST
Name : AuthRoot
Name : TrustedPeople
Name : My
Name : SmartCardRoot
Name : Trust
Name : Disallowed
Name : AdfsTrustedDevices

#Browsing through the stores is pretty intuitive
PS Cert:\> dir Cert:\LocalMachine\My
Directory: Microsoft.PowerShell.Security\Certificate::LocalMachine\My
Thumbprint Subject
———- ——-
E31234DEF282437D167A64FD812342B650C20B42 CN=XXXXa
8912343319B07131C8FD1234E250DC67CBE08D7A CN=XXXX
69AD2C21912340919D186503631234A6F0BE9F7F CN=*.xxx.ca,XXX..

#Exporting a cert is something a little less intuitive
PS Cert:\> $ExportCert = dir Cert:\LocalMachine\Root | where {$_.Thumbprint -eq “892F212349B07131C12347F8E250DC67CBE08D7
A”}
PS Cert:\> $ExportCryp = [System.Security.Cryptography.X509Certificates.X509ContentType]::pfx
PS Cert:\> $ExportKey = ‘pww$@’
PS Cert:\> $ExportPFX = $ExportCert.Export($ExportCryp, $ExportKey)
PS Cert:\> [system.IO.file]::WriteAllBytes(“D:\Temp\CertToExportPFXFile.PFX”, $ExportPFX)

#same mess for importing
# Define The Cert File To Import
$CertFileToImport = “D:\Temp\CertToImportPFXFile.PFX”
# Define The Password That Protects The Private Key
$PrivateKeyPassword = ‘Pa$$w0rd’
# Target The Cert That Needs To Be Imported
$CertToImport = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $CertFileToImport,$PrivateKeyPassword
# Define The Scope And Certificate Store Within That Scope To Import The Certificate Into
# Available Cert Store Scopes are “LocalMachine” or “CurrentUser”
$CertStoreScope = “LocalMachine”
# For Available Cert Store Names See Figure 5 (Depends On Cert Store Scope)
$CertStoreName = “My”
$CertStore = New-Object System.Security.Cryptography.X509Certificates.X509Store $CertStoreName, $CertStoreScope
# Import The Targeted Certificate Into The Specified Cert Store Name Of The Specified Cert Store Scope
$CertStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
$CertStore.Add($CertToImport)
$CertStore.Close()

For import/export, I’d recommend using code¬†from here:¬†http://poshcode.org/?lang=&q=import%2Bcertificate

 

ADFS Proxy Trust certificate on WAP doesn’t auto renew

Once upon a time, the web application proxy for ADFS proxy started throwing error.

The Remote Access Management console could not do much complaining with an error code “the operation stopped due to an unknown general error” as always really helpful message.

Looking at the logs, the WAP was also complaining about establishing its trust with the ADFS server.

Fairly enough the ADFS proxy was also complaining about the trust saying that the proxy trust certificate had expired.

Back to the WAP and surely enough it was. However from the GUI I could not find any way to recreate the trust and had to use my DuckDuckGo powers.

So I found that the wizard had to be tricked for reinitialization prior to doing anything as in http://channel9.msdn.com/Events/MEC/2014/USX305

HKLM\Software\Microsoft\ADFS\ProxyConfigurationStatus

We need to set the ProxyConfigurationStatus REG_DWORD to a value of 1 (meaning ‚Äúnot configured‚ÄĚ) instead of 2 (‚Äúconfigured‚ÄĚ). Once that change is made, re-open the GUI. No reboot is required.

The Remote Access Manager should now allow you to re-run the configuration wizard.

I still don’t know why it would not renew, but given that the certification of the trust goes by every 2 weeks I will seen pretty soon.

Troubleshoot KMS

This is the recipe for a KMS activation. This should serve a minimum of 25 machines up to plenty.

You will need:

1 KMS server (aka kms)
1 network
1 or more server to be activated
1 Volume Product Key for your server to be activated
1 working DNS

First of all KMS uses DNS to find where the KMS server is. do a nslookup to find out if this is configure it. Please note the address and port

nslookup -type=SRV _vlmcs._tcp.domain.local
Server:  asterix.domain.local
Address:  172.24.1.20
_vlmcs._tcp.domain.local   SRV service location:
priority       = 0
weight         = 0
port           = 1688
svr hostname   = p1-kms1.domain.local
p1-kms1.domain.local       internet address = 172.24.5.126

Verify connectivity from the server to be activated to the KMS server using [address] and [port]

Do a

cscript.exe slmgr.vbs -dlv

to verify what you have. Expect the VOLUME_KMS_*_* channel.

Do a

cscript.exe slmgr.vbs -ato

to activate

and if you are looking for your keys, and not the key for the KMS server which you get from your MSFT licensing portal, go to technet: https://technet.microsoft.com/en-us/library/jj612867.aspx

Get a List of All Useless Group Policy Objects

I have another problem today. The problem is that the previous Group Policy administrator had no strategy. I have been the chosen one to clean up our Group Policy strategy. As a result there are bunch of Group Policy objects (GPOs) that go nowhere or do nothing.

I had noticed this powershell guys article, but it looked like utterly complex.

import-module grouppolicy 
 
function IsNotLinked($xmldata){ 
    If ($xmldata.GPO.LinksTo -eq $null) { 
        Return $true 
    } 
     
    Return $false 
} 

Function IsEmpty($xmldata){
    If ($xmldata.GPO.Computer.VersionDirectory -eq 0 -and $xmldata.GPO.User.VersionDirectory -eq 0) { 
        Return $true 
    } 
     
    Return $false 
}
 
$unlinkedGPOs = @() 
$emptyGPOs = @() 

#Search for NotLinked GPOs
Get-GPO -All | ForEach { $gpo = $_ ; $_ | Get-GPOReport -ReportType xml | ForEach { If(IsNotLinked([xml]$_)){$unlinkedGPOs += $gpo} }} 
 
If ($unlinkedGPOs.Count -eq 0) { 
    "No Unlinked GPO's Found" 
} 
Else{
	$unlinkedGPOs | Select DisplayName,ID | ft 
	$unlinkedGPOs | backup-GPO -path S:\ActiveDirectory\GPOBackups | select DisplayName,GpoID, BackupDirectory | ft
	$unlinkedGPOs | remove-gpo -Confirm
}

#Search for Empty GPOs
Get-GPO -All | ForEach { $gpo = $_ ; $_ | Get-GPOReport -ReportType xml | ForEach { If(IsEmpty([xml]$_)){$emptyGPOs += $gpo} }} 

If ($emptyGPOs.Count -eq 0) { 
    "No Empty GPO's Found" 
} 
Else{
	$emptyGPOs | Select DisplayName,ID | ft 
	$emptyGPOs | backup-GPO -path S:\ActiveDirectory\GPOBackups | select DisplayName,GpoID, BackupDirectory | ft
	$emptyGPOs | remove-gpo -Confirm
}

It is to be used simply and get some output list – or uncomment the warranty info and backup and then delete the nasty stuff.

DisplayName                                                 Id
———–¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬† —
Disable Outlook Cache                                       7aca484c-ebcd-4779-9bc8-b2fb8e7302d1
Turn Outlook Junk Mail Filter Off                           de14544c-39be-444f-ac53-089ca0bc65a8
Microsoft Office Trust Centre                               ed6fb632-fdd2-4718-96b0-b3981b4145bd

DisplayName                                                 Id
———–¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬† —
Portal Home page — mandatory¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬† bbc9efe7-05c3-4187-92ac-948772f50bf8

Please note that GPO backup ID during the Backup-gpo is not the GPOID!

Extending the AD delegation wizard

I found myself trying to reorganize IT teams while focusing on security – also because there was no time to analyze logs to see who did what.

AD permission can be tweaked to infinity and beyond while most of the time IT shops just use the same permission roles. That’s when I noticed that the default delegation wizard did not offer much of those roles.

The default settings will only describe 13 “roles”. Microsoft documents how to extend this to 70 common roles here with the infamous appendix O. The article points to C:\%WINDIR%\inf which is fine for Windows Server 2003 I think. Anything above will be in c:\%WINDIR%\system32 directly. You can obviously tweak it to your liking and follow the other infamous kb 308404.

Once you have that it should be easier to delegate security by roles.

This said, you will still need tools to find out what the current permissioning is and how to clean it.  My favorite, Liza, is a free tool for Active Directory environments which allows you to display and analyze object rights in the directory hierarchy.

With the CLI, the assigned permissions can be display in the form of access control entries (ACE) with the command tool DSREVOKE and can be removed too.

More traditionnal dsacls or ADUC should do the trick but is way less intuitive.

Microsoft also lists some of them here.

Viewing queues in Exchange 2013 with powershell

Now that Microsoft have changed all the GUI management I struggled to locate the queue viewer. As it turns out it is NOT part of the Exchange admin center (https://localhost/ecp). This tool is part of the Exchange Toolbox, you will find with your management package for Exchange and the queue viewer works like before.

But obviously one would prefer powershell to do so, right!

Get-Queue and Get-QueueDigest will be you friends. You would need to know your DAG prior to that…

>Get-DatabaseAvailabilityGroup

Name             Member Servers                                      Operational Servers
----             --------------                                      -------------------
MY-DAG1         {MY-TOR-EX2, MY-TOR-EX1}

>Get-QueueDigest -Dag MY-dag1

GroupByValue                      MessageCount DeferredMess LockedMessag StaleMessage Details
ageCount     eCount       Count
------------                      ------------ ------------ ------------ ------------ -------
[10.77.77.12]                     227          0            0            0            {MY-TOR-EX2\66427, MY-TOR-EX...
Submission                        1            1            0            0            {MY-TOR-EX2\Submission}

Removing a KB for MS Office is not removing a KB for Windows

Sometime there are bad KB/patches. The patch in particular was KB 3055034 ‚Äď October 13, 2015, update for Office 2010.¬† Normally the procedure to uninstall a patch is to use SCCM to push out the following Windows Update Stand Alone tool command:

WUSA /uninstall /kb:3055034

However this only works with Windows Operating System Updates (which are deployed in the MSU format).  When dealing with a software product update like this one for Office, the correct answer is to look in the registry for information about the update.

Browse to: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\, and then search for the KB number of the update you need to remove. Once found, look at the Uninstall String, and you’ll see a value like this:

“C:\Program Files\Common Files\Microsoft Shared\OFFICE14\Oarpmany.exe” /removereleaseinpatch “{90140000-0011-0000-0000-0000000FF1CE}” “{55ECF9C7-CD5C-4E82-A83E-8113A956F906}” “1033” “0”

This command will remove the offending patch, but requires manual intervention (clicking Yes) and then will force a restart.  You can use these values with an MSIexec command though to run the removal of the patch through Windows Installer, which will allow for logging and standard reboot controls, etc.

Use this example to help you create your MSI command:

msiexec /package {90140000-0012-0000-0000-0000000FF1CE} MSIPATCHREMOVE={55ECF9C7-CD5C-4E82-A83E-8113A956F906} /qb /norestart /l+ c:\windows\ccm\logs\KB3055034_uninstall.txt

Roll this out in a Task Sequence and you should be on your way. This may force the shutdown of Office, and will not complete until the system has restarted, however.