DBATools 2.x certificate chain issues

If you are moving from DBATools 1.x to 2.x the way DBATools connec to the servers has changed. DBATools are using Microsofts new drivers to connect and the driver will by default check the certificate of the server to use a encrypted channel to talk to the server. If you haven’t enabled the SQL Server to use Certificate when creating the connection you have the choice of first doing

$Conn = Connect-DbaInstance -SqlInstance xxx -TrustServerCertificate

This will connect to the server and trust its self signed certificate. Or you can set DBATools to always trust the certificates.

Get-DbatoolsConfig -FullName sql.connection.trustcert # should see the value set to false
Set-DbatoolsConfig -FullName sql.connection.trustcert -Value $true

This will set the config value for the current session. To set it permanent you will have to register the settings.

Get-DbatoolsConfig | Register-DbatoolsConfig

Remember, if you do the second option and if you later add real certificates to the sql server. You have to change the setting back

Reset-DbatoolsConfig -FullName sql.connection.trustcert

syspolicy_purge_history

Multiple SQL instances problem

If you have multiple sql instance on the same server or cluster you might end up with a problem with the SQL Agent job syspolicy_purge_history. The job doesn’t fail but it might try to login to the wrong sql server instance on your server. I found this on one of my clients installation and when I tried it in my lab setup I had the same issue. This was tested on SQL Server 2019.

The issue is well described [here](https://www.codykonior.com/2015/05/31/login-errors-with-syspolicy-purge-history/) by Cody Konior

I have been using Codys solution without any problem on the instance where this issue have been a problem. So creds go to Cody for the below solution.

Exec	msdb.dbo.sp_update_jobstep @job_name = 'syspolicy_purge_history', @step_name = 'Erase Phantom System Health Records.', @step_id = 3, 
		@command=N'$applicationName = "SQLPS ($env:USERNAME@$env:COMPUTERNAME)"
$SQLServerConnection = New-Object System.Data.SqlClient.SqlConnection
$SQLServerConnection.ConnectionString = "Data Source=$(ESCAPE_NONE(SRVR));Initial Catalog=master;Integrated Security=SSPI;Application Name=$applicationName"
$PolicyStoreConnection = New-Object Microsoft.SqlServer.Management.Sdk.Sfc.SqlStoreConnection($SQLServerConnection)
$PolicyStore = New-Object Microsoft.SqlServer.Management.Dmf.PolicyStore ($PolicyStoreConnection)
$PolicyStore.EraseSystemHealthPhantomRecords()
'
Go

If you are not using policys this problem is just about a failed login on a different sql instance. But for me that is annoying enough to fix it.

It should be noted that you can just disable the step if you aren’t usin policys.

Microsoft VPN Split tunnel

While setting upp a VPN to my home so that I could access my home network and the lab servers I have there, I wanted to use split tunneling to avoid sending all traffic to over my VPN.

To do this I used Powershell and the following code

$VPN = @{
    L2tpPsk               = 'Your Shared secret key'
    Name                  = 'Connection name'
    ServerAddress         = 'x.x.x.x'
    AuthenticationMethod  = 'MSCHAPv2'
    EncryptionLevel       = 'Maximum'
    SplitTunneling        = $True
    TunnelType            = 'L2TP'
    UseWinlogonCredential = $false
    RememberCredential    = $True
}

$VPNRoute = @{
    ConnectionName    = $VPN.Name
    DestinationPrefix = 'y.y.y.y/24'
}

Add-VpnConnection @VPN -force
Add-VpnConnectionRoute @VPNRoute

I choose to use splatting to make it easier to read and I think the code is easier to read also. I don’t use the windows credential in this connection so I have to start it and set the user and password to be able to connect.

The route is needed for me to access the local network at home since I use a split tunnel. If I had more networks behind the VPN you can add more routes.

SSRS – Kerberos Authentication double hop

Reporting Services normally uses NTML as authentication when you install it but you can set it up for Kerberos Authentication with some work. The account that SSRS will use, can be one of the following three.

  • Virtual Account
  • Network Service
  • Domain Account

Of these three the Virtual Account will not share resources with other applications. The Network Service Account will be shared with other resources. The Domain Account can share but that is up to the admin to decide. So the best options is to choose between Virtual Account and Domain Account

To see how to setup Kerberos Authentication for SSRS a new lab was created with a Domain Controller, two SQL servers, two SSRS servers, two clients one Windows 8 and one Windows 10. Two service accounts where created RS1 and RS2.
SQL Server was installed with SQL 2019 and Reporting Services was 2019 stand alone installation.
In the domain a group policy was created to have webpages that uses the fully qualified domain name aka *.my.lab

Zone assignment

SSRS1

Reporting Services was setup with a virtual account for the service and a domain account to connect to the Reporting database. The domain account RS1 was used due to the fact that SSRS recommends that you don’t use a virtual account, aka computer account, to connect to the SQL server. If you use the virtual account to connect the report database it can lead to problems.

On the SSRS1 servers computer account the delegation was set to “Trust this computer for delegation to specified services only” and it was delegated to SQL1 that holds the database that we will run the report against.

No SPN record was created since it will use the HOST SPN

SSRS2

SSRS2 server was setup with a domain account RS2 for the Reporting Server service and the same account was also used to connect to the SQL Server for the reporting database.

For the domain account RS2 you need to create SPN record. By the documentation at Microsoft Docs SPN records was created of type HTTP/ComputerName and HTTP/ComputerName.domain. The SPN records where created by

SETSPN -S HTTP/ssrs2.my.lab rs2
SETSPN -S HTTP/ssrs2 rs2



The SPN records needs to be created before you can access the delegation tab for the user. The delegation was setup as the same way as for SSRS1 computer account in the image above. If there isn’t a delegation tab for the user account then the SPN records hasn’t been created correctly or you haven’t reloaded the domain.

For both SSRS servers the config file rsreportserver.config was modified. In the <Authentication> section <RSWindowsNegotiate /> was added so it looks like the code section below

<AuthenticationTypes>
	<RSWindowsNegotiate />
	<RSWindowsNTLM/>
</AuthenticationTypes>

After the change to the config file the servers was restarted and client was restarted.

In order to see that we are connecting with Kerberos or NTML you can use the following query

SELECT  s.session_id
	, c.connect_time
	, s.login_time
	, s.login_name
	, c.protocol_type
	, c.auth_scheme
	, s.HOST_NAME
	, s.program_name
FROM sys.dm_exec_sessions s
  JOIN sys.dm_exec_connections c
    ON s.session_id = c.session_id

Edge Chromium

HTTP://ssrs1/reports can access the report server and access the report that was created that queries SQL1.

HTTP://ssrs1.my.lab/reports can access the report server and access the report that was created that queries SQL1.

HTTP://ssrs2/reports can access the report server and access the report that was created that queries SQL1.

HTTP://ssrs2.my.lab/reports can access the report server and access the report that was created that queries SQL1.

The result of the above TSQL query was that all Edge Chromium was done over Kerberos authentication

IE 11

HTTP://ssrs1/reports can access the report server and access the report that was created that queries SQL1.

HTTP://ssrs1.my.lab/reports can access the report server and access the report that was created that queries SQL1.

HTTP://ssrs2/reports can access the report server and access the report that was created that queries SQL1.

HTTP://ssrs2.my.lab/reports can access the report server and access the report that was created that queries SQL1.

The result of the above TSQL query was that all Edge Chromium was done over Kerberos authentication

All looks good and we are done, well that is until someone needs to do some remote administration to SSRS2 like adding the server to Server Mananger

Server Manager error
Windows Admin error
PowerShell 7 Error

The above errors are due to the fact that we have said that HTTP is used by the RS1 account and not by the Computer Account.
To solve this is to remove the SPN we just created. But when we remove the SPN Kerberos double hop will stop working.

SETSPN -D HTTP/ssrs2 rs2
SETSPN -D HTTP/ssrs2 rs2

According to SPN documentation you could add port to the SPN, just using http in the test

SETSPN -S HTTP/ssrs2.my.lab:80 rs2
SETSPN -S HTTP/ssrs2:80 rs2

After adding the above SPN restart the server and the client used in the test. This time when accessing http://ssrs2/reports and http://ssrs2.my.lab/reports a login prompt is displayed. So even if the SPN documentation says you can use ports it will not work with SSRS at least. Though this solution solved the PowerShell remote problem.

CNAME

Another solution that could work is to use a CNAME to access the SSRS. After the CNAME report2 is created for ssrs2 the SPN should be created

SETSPN -S HTTP/cname.my.lab rs2
SETSPN -S HTTP/cname rs2

After a reboot to server and client (just to make sure) the test in Edge Chromium results in that we again gets a login prompt. Looking in the clients event log System shows an error for Source-Kerberos

Kerberos error in System log

A solution for this error when using CNAME I haven’t found so far.

A-Record

Instead of using a CNAME an alternative is to use a different A-record. Using an A-Record means that you have to use static IP addressing to the server either by do a static DHCP record or by using static IP on the server.

After the A-Record in the DNS server is created, the SPN record needs to be created on the service account

SETSPN -S HTTP/arecord.my.lab rs2
SETSPN -S HTTP/arecord rs2

Accessing the report server now by using http://arecord.my.lab/reports and http://arecord/reports works without any problem.
Accessing the report server by its hostname will result in a login prompt that will not go away.

Conclusions

So far my testing of SSRS and double hop is that using the virtual account with Kerberos delegation on the computer account is the easiest way to achieve the double hop to the source from the SSRS server. If domain account must be used for the service account then an other A-record is needed to not break remote administration.

SQL Server 2012 SQLPS.exe problem

For security reasons it was decided to remove PowerShell 2.0 on our servers and install PowerShell 5.1. It was tested on a few server but not with SQL 2012 installed on it. After PowerShell 2.0 was removed it was noticed that the agent job “syspolicy_purge_history” wasn’t working correctly. Further research show that SQLPS.exe was unable to start and crashed with an error. The problem didn’t occur on SQL 2014 and higher.

Working with Microsoft it was concluded that there where no problem with the server or PowerShell and the problem must be related to SQLPS.exe or the SQL server. When comparing a Window server 2016 that had both SQL 2014 and SQL 2012 installed and the agent job worked on SQL 2014 but not on SQL 2012. It was discovered a difference at folder “C:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn” and “C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Binn”. For SQL 2012 a file called SQLPS.exe.config was missing. Copying the file from SQL 2014 to SQL 2012 it all started working.

Pester

If you are using PowerShell and wants to test the code you are writing so that your functions is working as you expect, you should start to look at Pester.

Don Jones and Adam Bertram has a very good book about Pester on LeanPub

Here I will share my problems and learnings about Pester.

When I started reading the book I had Pester 3.4 installed as default by Microsoft on a Windows 10. But the pester test from the book was failing for me. The answer was to upgrade Pester to the latest version. After that the Pester tests worked perfect!

 

Windows 8 add shutdown, restart and logoff tile to windows 8

I’m trying out Windows 8 on my spare laptop and while I find Win8 to be good and solid OS I like many others miss the start button. Though I dont miss it that much what I miss more is an easy way to shutdown and restart. Of course you can hit ctrl-alt-F4 to get the shutdown/restart windows.

I wanted an easier way and while looking into another script I found this script at technets script gallery. This Powershell module allows you to create tiles for shutdown, restart and log off in the windows 8 start menu.

Error 2738. Could not access VBScript run time for custom action.

Found the solution below on this blog

Fixing Error 2738 on Windows 7 64-bit

If you have a 64-bit operating system, you will need to follow these steps:

Open a command line window as Administrator, which requires clicking Start typing cmd in the search box, then right-clicking on the cmd.exe program and choosing Run as Administrator. Next paste the following in the command line and hit enter.

reg delete "HKCU\SOFTWARE\Classes\Wow6432Node\CLSID\{B54F3741-5B07-11CF-A4B0-00AA004A55E8}" /f

That previous command removes the incorrect entry for VBScript support on 64-bit Windows 7. Next you need to make sure VBScript is properly registered by typing:

c:\windows\syswow64\regsvr32 vbscript.dll

or simply regsvr32 vbscript.dll if you are already in the syswow64 directory.

After following these steps you should be able to install your program without issue.

 

Fixing Error 2738 on Windows 7 32-bit

For a 32-bit operating system, the steps are similar, but slightly different:

Open a command line window as Administrator, by clicking Start, typing cmd in the search box, then right-clicking on the cmd.exe program and choosing Run as Administrator. Next paste the following in the command line and hit enter.

reg delete "HKCU\SOFTWARE\Classes\CLSID\{B54F3741-5B07-11CF-A4B0-00AA004A55E8}" /f

That previous command removes the incorrect entry for VBScript support on 32-bit Windows 7. Next you need to make sure VBScript is properly registered by typing:

c:\windows\system32\regsvr32 vbscript.dll

or simply regsvr32 vbscript.dll if you are already in the syswow64 directory.

After following these steps you should be able to install your program without issue on a 32-bit version of Windows 7.

Delete paging file when making an image of Windows XP.

Doing an image of Windows XP I wanted the image as small as possible.To achieve this I wanted the paging file removed from image using sysprep.exe. Thankfully Microsoft has a KB about this (KB892104)

One method and the one I use is

  1. Click Start, click Run, type regedit in the Open box, and then click OK.
  2. Locate and then click the following registry subkey:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management

  3. In the right-pane, double-click PagingFiles.
  4. Type c:\pagefile.sys 0 0 in the Value data box, and then click OK.
  5. Quit Registry Editor.
  6. Restart the system.
    Note A temporary page file that is between 10 and 20 megabytes will be created.
  7. Run the Sysprep.exe tool. The setting of the page file on the target system is resized during the first start to match the new system’s memory model.