(maint) .gitignore add .idea
(#17031) Add SID.octet_string_to_sid_object

 - This will allow a WIN32OLE instance returned by the connect method
    to convert its objectSID property (an octet stream / array of bytes)
    to a standard user friendly SID object
(#17031) Add SID.name_to_sid_object

 - Simple wrapper around creating new SID instances
 - Used to insulate tests from Win32::Security
 - Existing name_to_sid now delegates to this method
(#17031) Parse ADSI usernames -> domain / account

 - User names were previously naively accepted without checking if
   they were qualified with a host or domain
(#17031) group type #insync? #is_to_s #should_to_s

 - Delegate to provider implementation in the following cases
   insync? calls members_insync?
   is_to_s calls members_to_s
   should_to_s calls members_to_s
 - This basic contract lays down the framework for Windows support.
(#17031) Puppet::Util::ADSI.sid_uri

 - Allow for creation of WinNT://<SID> style uris
(#17031) Use SIDs to modify ADSI group membership

 - New #add_member_sid / #remove_member_sid methods do the heavy
   lifting inside of Puppet::Util::ADSI::User to add / remove group
   members instead of relying on string names
 - Expose a new Puppet::Util::ADSI::User#sid method that returns
   a Win32::Security::SID instance with account, domain, and raw SID
 - Puppet::Util::ADSI::User#uri method now uses the #sid account and
   domain to build a URI
 - Since #uri now relies on #sid, which converts the binary value from
   the #native_user.objectSID byte array, the @native_user is initially
   populated by generating a throwaway uri built by parsing @name.
   This prevents a circular reference.  This effectively means the
   original given @name is parsed and given to ADSI.connect, and on
   connect, the raw SID generates a SID object.  Alternatively, a SID
   could have been generated by Win32::Security::SID first, its domain
   and account values then used to retrieve @native_user.
   Original semantics around @native_user were kept intact to prevent
   breaking existing callers.  In practice, this should have no effect.
 - Due to dependence on Windows::Security, some tests are now run only
   on Windows.  This was a trade off where it would have been possible
   to add an initializer param for @sid to Puppet::Util::ADSI::User, but
   it seemed cleaner not to
(#17031) Prefer the domain component from the resolved SID

Previously, the `members_to_s` message included the SID string which was
difficult to read when the group has more than a few members.

Also, given a manifest with a fully qualified member:

    members => ['.\Administrator']`

The resulting `members changed` message contained:

    BUILTIN\.\Administrator

This is because `Win32::Security::SID#account` returns the value originally
passed to the constructor, .\Administrator. This doesn't actually affect the
group membership, since we always use the SID string in the ADSI connection
string, e.g. WinNT://S-1-5-32-*

This commit changes the message to prefer the domain component from the
resolved sid, e.g SID#domain, instead of the value the user entered, as the
former is the canonical version.

It also only prints the SID for each member when debugging is enabled.
Merge branch 'ticket/master/17031-windows-group-provider'

* ticket/master/17031-windows-group-provider:
  (#17031) Prefer the domain component from the resolved SID
  (#17031) Use SIDs to modify ADSI group membership
  (#17031) Puppet::Util::ADSI.sid_uri
  (#17031) group type #insync? #is_to_s #should_to_s
  (#17031) Parse ADSI usernames -> domain / account
  (#17031) Add SID.name_to_sid_object
  (#17031) Add SID.octet_string_to_sid_object
  (maint) .gitignore add .idea