Detect whether or not application is installed on remote server

When you manage a windows server in core mode you can’t just open Control Panel -> Programs and Features to see whether or not particular application is installed.

Here’s the command for it:

wmic /node:server product where "Name LIKE '%acronis%'" get name,version

To uninstall it:

wmic /node:server product where "Name LIKE '%acronis%'" uninstall

(The later doesn’t work always, probably depends on how uninstaller was written).

How to install PowerShell using PowerShell

This cmdlet is tricky to find in Google because searching for install powershell using powershell won’t give you much. So here it is:

Install-WindowsDeature PowerShell

or

Install-WindowsDeature PowerShell-V2

P.S. How to find exact name of particual Windows Feature to install?

Get-WindowsFeature | findstr PowerShell

Replacing the for loop with Seq.iter

Here’s the initial function in C#:

public string BuildQuery(IEnumerable<KeyValuePair<string, string>> args)
{
    var coll = HttpUtility.ParseQueryString(String.Empty, _urlEncoder);
    foreach (var arg in args)
    {
        coll.Add(arg.Key, arg.Value);
    }
    return coll.ToString();
}

First I rewrote it in F# the following pretty naïve way and forgot for a while:

member this.BuildQuery(args : IEnumerable<KeyValuePair<string, string>>) : string =
    let coll = HttpUtility.ParseQueryString(String.Empty, urlEncoder)
    for arg in args do
        coll.Add(arg.Key, arg.Value)
    coll.ToString()

But today I recurred to it and rewrote in better way:

member this.BuildQuery(args : IEnumerable<KeyValuePair<string, string>>) : string =
    let coll = HttpUtility.ParseQueryString(String.Empty, urlEncoder)
    args |> Seq.iter (fun arg -> coll.Add(arg.Key, arg.Value))
    coll.ToString()

How to make Beyond Compare default diff and merge tool in Git

Here’s a brief summary of the official documentation:

git config --global merge.tool bc3
git config --global mergetool.bc3.path "c:/program files (x86)/beyond compare 4/bcomp.exe"
git config --global diff.tool bc3
git config --global difftool.bc3.path "c:/program files (x86)/beyond compare 4/bcomp.exe"

Don’t ask me why BC4 has the shortcut called BC3 still. Go figure. And happy merging! :)

Enrollment policy server URI

If you try to request a certificate from non-domain joined machine using the certificates snap-in (CertMgr.msc) then you need to install on the server hosting your Certificate Authority the following components:

(maybe you need just one of them but I’ve installed both)

and then enter its URI in the following format:

https://<FQDN>/ADPolicyProvider_CEP_Kerberos/service.svc/CEP

How to configure RDG behind NAT

(As a recent promise to myself I put down every successfully solved problem anyhow worth to share)

This week problem was to make working the Remote Desktop Gateway located behind a NAT. Here’s the lesson learned:

  • Issue an SSL certificate with subject matching public DNS name (FQDN)
  • Use default port 3389/TCP otherwise SSL certificate name won’t match FQDN returning an error:

    The computer can’t verify the identity of the RD Gateway.

    or if you put it to current user’s Trusted Root Certification Authorities:

    Your computer can’t connect to the computer because the Remote Desktop Gateway server address requested and the certificate name do not match.

  • Publish HTTPS port 443/TCP as well otherwise connection won’t be established returning another meaningless error:

    Your computer can’t connect to the remote computer because the RDG server is temporarily unavailable.

That’s all, folks!

How to re-create symlinks of VM configs in Hyper-V using PowerShell

Hyper-V keeps VM configs at %ProgramData%\Microsoft\Windows\Hyper-V\Virtual Machines\ as a symlink to the original location.

You may get them broken due to various reasons, e.g.:

  • Server disaster
  • Upgrade to next version of OS/Hyper-V and then rollback
  • Migration

To restore functioning you need to create a symlink for each xml config, i.e.:

mklink %ProgramData%\Microsoft\Windows\Hyper-V\Virtual Machines\{guid}.xml d:\MyVM\Virtual Machines\{guid}.xml

But how to automate this if you have tens of VMs? Here’s the command:


Get-ChildItem -Recurse *.xml | New-Symlink -LiteralPath { Join-Path -Path '%ProgramData%\Microsoft\Windows\Hyper-V\Virtual Machines\' -ChildPath $_.Name } -TargetPath { $_.FullName }

How to select Azure subscription if you have more than one using PowerShell

If you have more than one Azure subscription in your account and try to upload a vhd using the instruction:

  1. Get-AzurePublishSettingsFile
  2. Import-AzurePublishSettingsFile d:\credentials.publishsettings
  3. Add-AzureVhd -LocalFilePath d:\my.vhd -Destination http://example.com/blob/container

You may get an error saying that selected account doesn’t have given blob.
That’s because the first subscription is selected by default and the target blob is in the another one.

To select the proper subscription use the following command:

Get-AzureSubscription | Select -Last 1 | Select-AzureSubscription

(For instance, the last one).

Could not load file or assembly ‘Microsoft.AnalysisServices, Version=11.0.0.0

If you’re getting the following error upgrading TFS 2012 RTM to ver. 2012.3:

TF255356: The following error occurred when configuring the Team Foundation databases:
TF400711: Error occurred while executing servicing step Upgrade Warehouse for component UpdateWarehouseVersion during FinishInstallUpdates: Could not load file or assembly ‘Microsoft.AnalysisServices, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91‘ or one of its dependencies. The system cannot find the file specified.. For more information, see the configuration log.

then just install Microsoft SQL Server 2012 Analysis Management Objects from Microsoft SQL Server 2012 Feature Pack (expand the Install Instructions node).

Note that you may need to restart tge setup wizard, or even server itself before error will gone.