Monthly Archives: October 2015

Loading VisualBasic code in Powershell to find out I didn’t need it

Working in a multi domain environment, I needed the NETBIOS name of the server domain. I eventually got a very simple VisualBasic code block to work in Powershell, but found out it was not what I was looking for. A differentiation did give me what I needed but it proved to be a method not worth using.

I was working on different ways to determine the NETBIOS DomainName of a Windows server (in the server context, not the user context).
I found some information using [ADSI] (Active Directory Service Interfaces) in Powershell, but I also found a reference to WinNTSystemInfo, but using vbscript.

It seemed to me that this VBScript object should be easy to (re)create in Powershell. It looks like I didn’t got that part right.

When I finally found a way to get the domain name out of the WinNTSystemInfo object using VisualBasic inside Powershell, it provided me with the Domain in the User context


The same page I found also referenced the ADSystemInfo VB Object, so I gave that a try with the same Powershell Add-Type method.

This time it did give me the server domain NETBIOS name, this is the code that I got working:


In the end I have found another reference, which included the WMI object Win32_NTDomain, again a VBScript / VisualBasic scenario, but using WMI is easy in Powershell:

This could give numerous domains, because in the case the user is from another domain than the server, it gives both. I haven’t found a way to determine which domain is the user domain, but you could use a Where clause, like (Get-WmiObject Win32_NTDomain | ?{$_.DnsForestName -like ((Get-WmiObject Win32_ComputerSystem).Domain) }).DomainName, or maybe this [DirectoryServices.ActiveDirectory.Domain]::GetComputerDomain().Forest (or GetComputerDomain().DomainControllers.Forest).

Using ADSI it would be this using Powershell:


This does provide the NETBIOS DomainName in the server context.


So keeping it to Powershell without VisualBasic is much easier.


SPTrustedIdentityTokenIssuer URI invalid

This week a problem occured on our SharePoint environment due to human error, but with unexpected SharePoint behavior driving the cause and troubling the solution.
Somehow it is possible to update the SPTrustedIdentityTokenIssuer property ProviderSignoutUri with an invalid value, and all subsequent repair actions will fail, as well as many SPTimerjobs. All give the same error “Invalid URI: The format of the URI could not be determined”.


The SPTrustedIdentityTokenIssuer cannot be deleted or altered (while it’s in use), the WebApplications cannot be altered or updated (and they use the SPTrustedIdentityTokenIssuer), the timerjob RefreshCache fails everytime, even solutions cannot be installed or uninstalled.

We found out that, although the .Update() action triggered an exception, the attribute does get changed in the database. When displaying the properties of the SPTrustedIdentityTokenIssuer however, the attribute seemed empty. This made us go on a wild-goose chase, until we checked everything again and determined that the problem didn’t pre-exist and it had to be related to the SPTrustedIdentityTokenIssuer object.
So I dug a little deeper and decided to look in the SharePoint config database:

In the resulting row, the properties column contains a large XML with all configuration related to your TrustedIdentityTokenIssuer.

Here we found out that the attribute “ProviderSignoutUri” was populated with a value, the human error had somehow appeared in the SharePoint Configuration Database, although it wasn’t visible with the Powershell command Get-SPTrustedIdentityTokenIssuer, it appeared empty! This left us with no other choice than to change the value with SQL (UNSUPPORTED). Make a back-up of your database before you attempt this fix. Make sure you copy the whole XML to your UPDATE statement and only change the row with the Id of the TrustedIdentityTokenIssuer!


When the SQL UPDATE statement has been executed, update the object from Powershell commandline without any alteration and you are good to go again.

So, SharePoint allows us to change the attribute to an invalid value, gives us an exception about it, but changes it in it’s SharePoint Configuration Database, and furthermore wont show the actual value and won’t let us change anything related to it. Don’t want anyone to have to go through all this.





For future reference, here are some details of the exceptions and the logfiles.

The ULS logfile entries of the first occurrence and the resulting timerjob failure:

Saving passwords securely in Powershell

When dealing with passwords in unattended installations, the challenge is always if the password is securly stored.
One way to deal with it is to use “Read-Host -AsSecureString” on the target server from within the script.
But when dealing with a lot of passwords in 1 script, this will cause a lot of prompts.
You could save every password with the ConvertFrom-SecureString function, the default uses a User specific masterkey (through Data Protection API – DPAPI) so it can only be used when the script is run as the same user. Also it is easy to get the password through reversing this as that same user.

Get plain password from securestring:



To overcome both problems we need something better. This is where a custom key can be used with the ConvertFrom-SecureString function. The key must be in byte format and must be 16, 24 or 32 characters long.

Then you only have to ask once for a key and you can use that to decrypt all passwords that are stored in the script or in configuration files.

An alternative to this manually defined key is using a random 32bit key:

This random key is not a solution in itself, because you can’t remember it, so we need to provide this key and we can use a certificate, which provides encrypt and decrypt options of the previously used key. When encrypting the key with a specific certificate, we can provide the key to anyone who has the certificate that is needed to decrypt this key, after which we can use the decrypted key to decrypt the passwords.

In this case the steps would be:

  1. Create byte key (random generated, or a specific passphrase)
  2. Make securestrings of passwords
  3. Convert (encrypt) securestrings with key
  4. encrypt key with certificate
  5. provide encrypted key (or have it entered when its a passphrase) and encrypted passwords
  6. decrypt key with certificate
  7. decrypt passwords with the key

Read more on:

Convert pfx certificates to crt on Windows

The most cited and advised way to convert a pfx certificate file to crt, is to use openssl. For a Windows server I will look at alternatives using Powershell.

On a Windows server, openssl isn’t available, but if a small external download is an option, you can still find a Windows ported version of openssl, it really works as simple as advertised:

The warning can be ignored, it doesn’t impact the functionality.

For example:

OpenSSL For Windows URL:

Another way to do this on a Windows Server, is to use Powershell.

Depending on your Operating System version (Win2012+/Win8+) and Powershell version (V4+), this could be a one-liner:

The downside is, that it prompts for a password, so this cannot be used in an unattended script.


On older versions the command “Export-Certificate” is not even available, so for older versions and for unattended scripts this would be the trick:

Set-Content could be considered the easier readable approach, compared to “[System.IO.File]::WriteAllBytes()”.

#New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($cert)
#Object.Export(): Specify one of the following enumerator names: Unknown, Cert, SerializedCert, Pfx, Pkcs12, SerializedStore, Pkcs7, Authenticode


For exporting from your certificate store to a PFX file, you could use:

For importing from a PFX file to your certificate store, you could use: