Repairing the WS-Management service on the Windows server

Some features of the Windows 2019 server can easily and inadvertently be incapacitated and many seem to get screwed up on their own. And it is quite possible that one error triggers another and getting out of that tangled mess is very hard and time consuming. It takes a lot of time just to restore the basic functionality of the Windows server.

It took me months of on-and-off investigation to figure out how to persuade the DNS not to add an entry for each and every one of the server's IP addresses, because when it does so, the DNS queries return these different IPs in a round-robin fashion and this causes errors. And there are no good solutions on the internet, they all say that "Register this connection's addresses in DNS" should be unchecked, but that's not enough: you also need to unbind the DNS server from all IP addresses but one (it's in Properties-Interfeaces in the DNS app) and also removing the IPs from the Name Servers tab in your DNS zone's properties.

After I did this - and it may or may not be related - the Server Manager started reporting errors like "The WS-Management service is configured to not accept any remote shell requests." and because of this I was now unable to install or uninstall anything. I solved the by using PowerShell equivalent commands, but it worked for some tasks and for some it didn't. The predominant solution suggested on the net was to turn on AllowRemoteShellAccess using gpedit.msc, but it required me to do gpupdate /force and this in turn didn't work because of some policy replicating problem on Windows. And all the time, the stuff that worked in Windows still worked but it was a gamble trying to change anything on the server. There was a bunch of solutions on the internet for this but none of them worked: just using the File Explorer to browse through the problemmatic SYSVOL share, I got the impression that the domain shortcut that was there pointed to the wrong server - it actually pointed to the domain but that resolved to the wrong server's IP... I believe I did some tinkering in the DNS that may have helped but wasn't the final answer. In the end, a brute force solution was required, I just copied SYSVOL contents from the other domain server. (Having two domain servers could have been the root of the problem anyway, and possibly the DNS changes).

Back to the original WinRM problem, I was now able to turn AllowRemoteShellAccess on, to no effect. So I tried other suggestions - and once again, most solutions revolved around the same repeated stuff, none of which worked. Running winrm quickconfig returned "WsManFault" with error number -2144108526 0x80338012, saying "The client cannot connect to the destination specified in the request" and that I should run winrm quickconfig to configure the WinRM service. Issuing dir wsman:\localhost\Shell to check the active configuration said that the path does not exist, even if doing dir wsman:\ listed localhost as a result. A StackOverflow post suggested this bit of PowerShell scripting that finally shed some light on this:

$c = Get-Credential
New-CimSession -ComputerName localhost -Credential $c

Running this for localhost reported an error but did work if I used the name of my server. So WinRM worked, but not on localhost?!

I found the final bit of information on Robin CM's IT Blog, here somebody finally approached the problem instead of repeating the same mantras already present on the internet. Running netstat -aon | find "5985" to find what IP address is the WinRM port (5985) bound to (and note that this is command prompt, not Powershell) returned:

TCP              LISTENING       4

So the service really is bound to the external IP and not localhost!

The blog post suggested I do netsh http delete iplisten, but it seemed too drastic to me - from what I understand, this is actually the IIS binding (I could be wrong) and I didn't want IIS listening on all IP addresses. So I simply added localhost to the list (this was OK for IIS) and it worked:

netsh http add ipaddress=

(note that I also did iisrestart, which may or may not be necessary). The Server Manager now works and winrm quickconfig stopped erroring out... In the end, I don't have AllowRemoteShellAccess configured in the GPO at all, it allows the connections by default, and dir wsman:\localhost\Shell now shows this with no complaints.

Now let's see what else is faulty... How about "Windows cannot access the specified device, path, or file." when the settings app tries to run control.exe? No - maybe next year.

Short tips to getting Excel working with ASP.Net Core OData service

I've been tinkering with an Asp.Net Core OData service designed to be consumed by the Excel client... There are a lot of details that will screw your brains if you don't get them right, and it doesn't help that ASP.Net is a fidgety beast in that bits move around in each version and there are more examples on the net that don't build than the ones that do. I could do a separate post for each of them since it's very hard to get relevant information, but for the time being I'll just list them here.

For one, older versions of Excel (pre-2016) have some OData support but it doesn't seem to be adequate, it's best to install the Power Query plug-in and use that for OData. In 2016 and later, be careful as there are two OData options - under Get External Data and under New Query... You want the second one.

If you need authentication, don't count on using OAuth (which was what I would have expected - OData, OAuth, right?). Excel supports basic, windows, web api (i.e. some kind of a security key) or organizational account (which I suppose is AD). My users are stored in my application database, so the only way was to use the basic authentication... Which is so deprecated that Asp.Net guys refuse to support it and I had to roll my own. (Not too difficult, there are examples on the net, but additional work nevertheless).

There's a ton of examples on how to implement a trivial Asp.Net OData service that returns data from a single Entity Framework-mapped table. I haven't found (m)any that show how to use more complex SQL queries. Because, if you need this data in Excel, you'd like to have complex query - or not? Apparently nobody thought about that. There's an open source component called DynamicODataToSql that understands the OData data-shaping commands and can convert them to SQL. Well - only if the SQL you start with contains a single table name... Uhm, at least it could be a view in the database, I guess EF can do that as well. But with a couple of modifications, this component can be persuaded to at least treat what you give it as a nested SQL query (turning it effectively into a table) and add its magic on top of that.

Also, Asp.Net doesn't know how to return appropriate errors through OData, it spits out an HTML error page whereas a Web API is supposed to return XML or JSON. So, more manual labour: solutions exist online on how to add a filter that does this, but it's not supported out of the box. Still, even with this, Excel seems to sometimes ignore some errors. Especially in the query editor window, the preview that it shows isn't necessarily the data that it pulled from the server at that precise moment (as in: you see your code throwing an exception on the server side but Excel pays no attention and still shows data). The best way to check if the service works seems to be to load the data into a sheet and refresh it from there.

And the final headbanger - for now, at least - was how to get Excel to do server-side data shaping. Because, for unknown reasons, it sometimes decides to load everything from the database and then filter data by itself... Which is insane. One important bit I found that makes or breaks this is the URL you give Excel to access the data. If you target your OData controller directly (e.g. http://localhost/odata/MyData), everything will seemingly work but the data will be filtered on the client. If the URL points to the base OData directory (e.g. http://localhost/odata), Excel's editor will add a Navigation step to the query to select the controller - and with this the server-side filtering will work. Now, I'm talking only about filtering as I'm not sure if Excel supports other OData stuff like grouping: filtering is fundamental and I'm OK with counting the rest - especially given all the problems listed above - as a bonus.

VisualStudio install cache folder is important

I tried to find information about the "VisualStudio install cache" folder that Visual Studio installer creates, but was unable to find much. The folder takes a healthy couple of gigabytes of disk storage and, having the "cache" keyword in it, seems to be safe to delete. But deleting it will cripple Visual Studio updates. My Visual Studio 2017 started saying that its version is and that everything is up to date, while for Visual Studio 2019 the update tool reported missing arguments. (Also, trying to start the same tool from command prompt with different arguments resulted in the maddening "Sorry, something went wrong" error message).

The main reason for this is the most important part of that folder, and that is Packages/Instances. This is where the installer seems to keep the information about your Visual Studio's current state. There's a folder for each installed Visual Studio instance - and the number seems to be random which makes sense because you may have multiple instances of the same (or same-ish) version of Visual Studio: you can have, for example, a release and a preview version of VS 2019. If this folder is lost, the installer won't know which versions you're on, your updates won't work, and the current installer refuses to install everything anew on top of an existing installation, so there's no easy way out. You will be forced to use install cleaner tools (probably without success), then delete the whole Visual Studio folder and install everything from scratch.

But Packages/Instances is not the only problem: when starting, the installer also seems to check for installation packages of installed extensions and won't work without them. These have semi-intelligible names but there's more than one folder for each extension, and some depend on external packages which have their own folders... Therefore, it's not easy to figure out which of the packages are important and which aren't. The unimportant ones can be deleted, the installer will complain about some but will know how to download and restore them so that everything is back to normal.

If you want to get rid of the excess packages, the regular way seems to be to run the installer with "--nocache" argument. (Or, use a more elaborate script from Microsoft). If that fails, you can make a backup of the existing content, remove everything you think you can do without (leaving the Instances folder is a must!) and then run the installer. It will complain that there was an error, and when you click Retry it will give the exact folder name for the first package it was unable to find so that you can restore it by copying the folder back. But you must repeat this for all missing packages - and I had more than ten, I think. At one point, clicking Retry will stop giving specific error messages (even if the installer reported an error), but the "install" button will become available and you will be able to click it to automatically download the rest of the missing stuff. I managed to shave off two thirds of my cache folder, reducing it from 3-4 gigs to slightly over 1 GB this way.

How to set a category for Visual Studio new item templates

A .vstemplate file defines a template for an item that appears in Visual Studio's "Add New Item" dialog. But it doesn't have an option to choose which of the categories (shown in the left part of the dialog) it will appear in.

Add New Item Category

I know of two ways to use the .vstemplate file and there are two different solutions to specify the category.

If you are simply copying the template to your Documents\Visual Studio XXXX\Templates\ItemTemplates\Visual C# or similar folder, just create a subfolder named the same as the category you want. It seems that Visual Studio processes these folders once when the first Add New dialog is opened and ignores further changes so it needs to be restarted in order to refresh.

If you have a VSIX add-in with a VS project containing item templates, you need to right click on an vsitemtemplate file in the Visual Studio solution explorer, choose Properties, and in the displayed properties window set the Category property to your desired category name. Note that the Category property is invisible unless the Build Action for the file is set to VSTemplate - but if it isn't, then the template won't work anyway.

Visual Studio property window for the vstemplate file

Subscribe to this RSS feed