Search This Blog

Sep 20, 2023

Make a MIT Kerberos client on Windows

Steps

  1. Compose krb5.conf file ( In windows, it's krb5.ini under %programfile%\MIT\Kerberos)
    1. concepts here
    2. samples here
      My sample file



    3. reference here
  2. Ktpass command to generate keytab file
    1. ktpass /out userName.keytab /mapuser userName@johnfoo.tk /princ http/serviceHostName.johnfoo.com@JOHNFOO.TK /pass <pwd> /crpto all /ptype KRB5_NIT_PRINCIPAL
  3. kinit to obtain ticket
    1. kinit -k -t userName.keytab http/serviceHostName.johnfoo.tk@JOHNFOO.TK
  4. klist to verify that ticket was issued successfully


Aug 4, 2023

Demo-parallel-foreach

 This requires PowerShell v7

$sub=New-Object System.Collections.ArrayList
$destSubs = [System.Collections.ArrayList]::Synchronized($sub)
$allsubs=@(1,2,3,4,5)
$externalVariable=3
$AllSubs | Sort-Object -Property Name | ForEach-Object -Parallel {

    # Any external variable reference needs to be localized using "using"
    $localVariable = $using:externalVariable
    ($_ -lt $localVariable)

    # Obtain reference to the bag with `using` modifier
    $localCostsVariable = $using:destsubs

    # Add to bag
    $localCostsVariable.Add($_)
}

$destSubs
write-host ""
$sub


# NOTE: many AD object properties won't be visible inside of a parallel script block.
# Need to trigger PS AD adapter driver to populate the result set first
# https://stackoverflow.com/questions/75851412/powershell-foreach-object-parallel-not-all-properties-of-piped-in-object-are-a
#

$users = get-aduser -filter $filter -properties samAccountName,lastLogonTimestamp
#$users=$users|select *    # uncomment this line in order to make below work
$users|foreach -parallel {
   [do something with $_.samAccountName]   # --> this works fine. samAccountName can be read properly
   [do something with $_.lastLogonTimestamp]    # --> this doesn't work. lastLogonTimestamp is always NULL regardless if it is actually populated

}

Jul 20, 2023

MS Graph RESTful Queries

  1.  Links
    1. Graph Explorer
    2. MS Odata Document
    3. Oasis Odata v4.0.1 URL Conventions, specifically, pay attention to 
      1. URL components
      2. Resource path and how to address entities, properties etc.
      3. Query Options
  2. An Odata URL is consist of 3 parts



    1. root URL: GET request made to root URL returns service document (that defines all resources available via the service)
    2. resource path: Entity or entity sets that are accessible via RESTful API
    3. Query option: select, filter, count, skip, order, top etc. See next section 
  3. Addressing
    1. Getting entity set:    GET serviceRoot/users
    2. Getting individual entity by key:    GET serviceRoot/users('john.doe@example.com')
    3. Getting entity property    GET serviceRoot/users/displayName
    4. Getting entity property raw value:    GET serviceRoot/users/displayName/$value
    5. Getting entity set:    GET serviceRoot/users
    6. Getting entity set:    GET serviceRoot/users
    7. Addressing metadata in powershell: $obj.'@odata.type'
      The key here is that the dot (.) between "odata" and "type" is not denotation of a sub-property, but just a normal text character as part of the property name '@odata.type' (so we quote the whole string)
  4. Query options
    1. Filter:
      1. Filter operators: eq/ne/gt/ge/lt/le/and/or/not/has/in
      2. Filter functions: contains/startsWith/endsWith/indexOf/concat/subString
      3. Collection functions: hasSubset/hasSubsequence
      4. More functions on Oasis URL above
      5. Example #1:    GET serviceRoot/users?$filter=upn eq 'johnDoe@example.com'
      6. Example #2, filter against complex type. This query finds airports whose address contains "San Francisco", where address is a property of a complex type Location:    GET serviceRoot/Airports?$filter=contains(Location/Address, 'San Francisco')
      7. Example #3:    GET serviceRoot/users?$filter=upn in {upn1@x.com,upn2@x.com}'
    2. Expand:
      1. Navigation properties: any property that can link to another entity. For example, "memberof", "manager" property of a user
      2. Example #1:    GET serviceRoot/users?$filter=upn eq 'johnDoe@example.com'$expand=manager
      3. Example #2:    $uObj=get-mgUser ... -expandproperty manager; $uObj.manager.additionalProperties.displayName
      4. Example #3:    get-mgUser ... -expandproperty "manager(`$select=displayName,jobTitle)"
    3. Select:
      1. Example #1:    GET serviceRoot/users?$select=*
    4. OrderBy:
      1. Example #1:    GET serviceRoot/users?$expand=manager($orderby=department)
      2. Example #2, order by the count of members:    GET serviceRoot/groups?$orderby=members/$count
    5. Top/Skip/Count
    6. any/all operator
      1. GET serviceRoot/People?$filter=Emails/any(s:endswith(s, 'contoso.com'))
  5. Literals
    1. null/$it/$root/$this
  6. placeholder