Friday, November 16, 2018

Testing new syntax

A colleague used some syntax that I hadn't seen before so I thought it would be worth testing in isolation.  The notation is an extension of the ternary conditional operator known as the null-conditional operator that was added as part of C# 6.0 in 2016.  I believe I need to up my C# game.  Anyway, here is the sample program I built:

which outputs:
We build our code using the null-conditional operator to avoid having to build out the more common tertiary version of the same code:

Wednesday, November 7, 2018

Stop RHEL from hibernating when laptop lid closes

Quick hit here, I installed Red Hat Enterprise Linux 7 on a decent, but old laptop to let me play with OpenStack in a semi portable way.  The only issue is that I want to close the lid and leave it running and still be able to attach to it.  Close the lid, power savings kick in.  To stop that, just edit:
and change:

Tuesday, October 23, 2018

Nested Hyper-V and NAT Switches

Quick and dirty, to nest Hyper-V instances you just need to run a quick PowerShell command to set a flag:

Set-VMProcessor -VMName <VMName> -ExposeVirtualizationExtensions $true

Another interesting find is Setting up a NAT switch for Hyper-V:

New-VMSwitch -SwitchName “NATSwitch” -SwitchType Internal

New-NetIPAddress -IPAddress -PrefixLength 24 -InterfaceAlias “vEthernet (NATSwitch)”

New-NetNAT -Name “NATNetwork” -InternalIPInterfaceAddressPrefix

Wednesday, October 11, 2017

Converting a datetime to a Client Specified string

How do you handle converting a couple of dates with times to a string for use in a report when the client has specific requirements around formatting that don't align with any of the TSQL standards?  You dig in and go hunting.  Specifically, the client wants the start and end date time values to be displayed in the header of a report as one of the following:

October 11, 2017 18:06 - 21:06
October 11, 2017 18:14 - October 12, 2017 07:14

See what I did there?  Notice that the month is fully spelled out?  See how we collapse the date if the times are on the same day?  Here is the code to do it:

The main trick is to just keep pulling off parts and representing them appropriately.

Wednesday, July 19, 2017

Reading Structured Binary files in C#: Part 17

Here we go again.  The last bit we did was pulling out the metadata stream headers which spat out this list:

Starting Address: 0x290
iOffset: 0x6C
iSize: 0x104
rcName: #~

Starting Address: 0x29C
iOffset: 0x170
iSize: 0x100
rcName: #Strings

Starting Address: 0x2B0
iOffset: 0x270
iSize: 0x1C
rcName: #US

Starting Address: 0x2BC
iOffset: 0x28C
iSize: 0x10
rcName: #GUID

Starting Address: 0x2CC
iOffset: 0x29C
iSize: 0x50
rcName: #Blob

for the HelloWorld_CSC_2.0.exe file I tested it with.  The first stream on the list is named #~ which means it is going to be fun to deal with because it is a compressed metadata stream.  The .NET IL Assembler book has a nifty drawing showing all 5 of the streams above:

and looking at the far right, you can see that we have yet another header to dissect.  The structure of the header is:

4 bytes
Reserved; set to 0.
1 byte
Major version of the table schema (1 for v1.0 and v1.1; 2 for v2.0 or later).
1 byte
Minor version of the table schema (0 for all versions).
1 byte
Binary flags indicate the offset sizes to be used within the heaps
.•        4-byte unsigned integer offset is indicated by 0x01 for a string heap, 0x02 for a GUID heap, and 0x04 for a blob heap
.•        If a flag is not set, the respective heap offset is a 2-byte unsigned integer
.•        A #- stream can also have special flags set: flag 0x20, indicating that the stream contains only changes made during an edit-and-continue session, and flag 0x80, indicating that the metadata might contain items marked as deleted.
1 byte
Bit width of the maximal record index to all tables of the metadata; calculated at run time (during the metadata stream initialization).
8 bytes
Bit vector of present tables, each bit representing one table (1 if present).
8 bytes
Bit vector of sorted tables, each bit representing a respective table (1 if sorted).

It is all nice and fixed, so it will be easy to get started so let's dig right into the metadata stream header for the metadata...what?  How about the metadata metadata stream header?  All this naming stuff is hard.

So, here is the code:
But there is a catch.  The bits in the MaskValid represent tables, and this is followed by a bunch of 4 byte unsigned integers for each '1' representing the number of records in the table.  I will work on that part next, this is good enough for now.

Keep compiling!

Wednesday, May 31, 2017

Great open source project for testing SharePoint email: MailCatcher

I had to configure SMTP on a SharePoint server where QA and Developers need to view the email output.  Normally I use SMTP4Dev to simulate my SMTP servers for development, but in this case I need to have the QA and Developers have access to the email without direct access to the server.  I looked around and found MailCatcher, a Ruby based program that acts as a SMTP server and web application.  To support MailCatcher I needed to install Ruby using the Ruby Installer for Windows.  The installation of Ruby is quite easy, and once it is installed the installation of MailCatcher simply requires a simple command:

gem install mailcatcher

Once it is running, I get a very pretty interface to give to my Developers and QA:

Monday, May 22, 2017

Open PowerShell as another user

This comes up quite often if you play around with PowerShell and SharePoint.  Just because you have Administrative rights in SharePoint, it doesn't follow that you can access a site programatically from PowerShell.  For that, you need to be granted Shell Admin rights on the content database that holds the site.  There are some accounts in SharePoint that are more privileged than others, and the farm account is one of those.  What you can do, assuming that you know the farm account credentials, is open up a PowerShell window as the farm account and run the Add-SPShellAdmin account with your credentials.  To open PowerShell as a different user, right click on the SharePoint 2013 Management Shell (PowerShell with Windows.SharePoint.PowerShell already loaded) shortcut, Shift+right click on the SharePoint 2013 Management Shell in the context menu, and choose Run as a different user:
Open PowerShell as a different user
That's it!  Short and sweet.