• Some time back I was trying to understand AD logon with the help of Wireshark  packet captures. The way I did the lab was as follows.

    1. net stop netlogon
    2. Run Wireshark
    3. net start netlogon

    The following course of events happen.

    1. Host reads the IPConfig and finds out the DNS suffix (e.g., MyDomain.local). It queries the DNS server for that domain.

    2. In particular, it searches for an SRV record in the DNS-query: _ldap._tcp.dc._msdcs.MyDomain.local

    3. The DNS server sends a list of DCs in the domain. In this lab, I have three AD sites, which are listed in the "Answers".

    4. The host sends LDAP request to a DC from the list. The DC will determine which site the host is in based on the IP subnet. If the host is from a different site, it will advise the host about the nearest DC.

    Once the host in communication with the DC, actual authentication and Kerberos  ticket granting happens.

    Troubleshooting "Slowness" in Authentication:

    1. Process is happening to individuals:

    • 2. I would check the logonserver  (PowerShell $env:logonserver):
     echo %logonserver%
    • 3. I would Pathping/Traceroute the DNS and DC to see if there is a network issue.
    • 4. I would Clear the logon cache
    net stop netlogon
    nltest /dsgetdc:MyDomain.local /force
    net start netlogon

    2. Process happening to all hosts in a domain:

    • echo %logonserver% to see if the hosts are authenticating to the DCs in the local network
    • I'd check the network connectivity
    • If multi site, I would check the subset definitions in the ADSites.
  • Glad that you fixed it.

    Just a note, I tend not use the "xx-yyy" as function names not confuse with the PowerShell's verb-noun convention (screenshot).  I try to force myself to be creative with '_" or capitalization in naming my function!

  • Sorry about the confusion.

    Registry does not give you an environmental variable but a complete path as I have shown below. I was using that environmental variable as as an example. Let me explain my code and logic.

    1. Registry is one of the options to explore applications in a code. There are 2 locations:

    • 64bit: HKLM:SOFTWAREMicrosoftWindowsCurrentVersionUninstall
    • 32 bit: HKLM:SoftwareWow6432NodeMicrosoftWindowsCurrentVersionUninstall

    2. Below is an example of Adobe Acrobat that uses 32 bit.

    (Sorry Wordfence won't let me share the script in the script mode.)

    $appString6432 = '*acro*' # assume you have adobe acrobat on the computer or replace it with any other app
    $reg6432 = 'HKLM:SoftwareWow6432NodeMicrosoftWindowsCurrentVersionUninstall*'
    $app6432 = Get-ItemProperty $reg6432 | Where-Object {$_.DisplayName -like $appString6432}

    $InstallLocation = $app6432.InstallLocation

    Running on the PS terminal:

    C:UsersRatan> $InstallLocation
    C:Program Files (x86)AdobeAcrobat Reader DC C:UsersRatan> tree $InstallLocation
    Folder PATH listing for volume Windows
    Volume serial number is 2E3F-D6FD
    No subfolders exist

    So, the code gives you a variable $InstallLocation with a value of C:PROGRAM FILES (X86)ADOBEACROBAT READER DC . When you process that variable you get an error. Something is missing in my understanding of PS variables!

  • as I mentioned earlier

    $appString6432 = '*acro*'     # assume you have adobe acrobat on the computer or replace it with any other app
    $reg6432 = 'HKLM:SoftwareWow6432NodeMicrosoftWindowsCurrentVersionUninstall*'
    $app6432 = Get-ItemProperty $reg6432 | Where-Object {$_.DisplayName -like $appString6432}
    $InstallLocation= $app6432.InstallLocation
    tree $InstallLocation
  • As you see in the original script I am using to get the address from the registry, I have to use the variable returned from $InstallLocation.

    I guess I could set a check if it is "C:Program Files (x86)" $p =${env:ProgramFiles(x86)}. But honestly, why would they stick that kind of folder naming while everyone knows its not code-friendly!

  • Here you can try this.

    $appString6432 = '*acro*'     # assume you have adobe acrobat on the computer or replace it with any other app
    $reg6432 = 'HKLM:SoftwareWow6432NodeMicrosoftWindowsCurrentVersionUninstall*'
    $app6432 = Get-ItemProperty $reg6432 | Where-Object {$_.DisplayName -like $appString6432}
    $InstallLocation= $app6432.InstallLocation
    tree $InstallLocation
  • Yes I tried that. Here is the problem.

    1. When you put, $env:ProgramFiles(x86) inside "", it removes the space between Programfiles and (x86). Therefore it will fail.
    2. The Windows folder is "C:Program Files (x86)" - there are 2 spaces in the string along with the parentheses.
    3. They deal with it in the environmental parameter by taking away the spaces. Also if you try on ISE $v = $env:ProgramFiles(x86), it will add {} to set a variable.
  • Hi Mike, thanks.

    Yes that works.

    $p=$env:ProgramFiles ; tree $p

    But things fail when you go for $env:ProgramFiles(x86) or you store 'C:Program Files (x86)' to a variable, as in the screenshots above.

    I figured out the trick would be to create a variable like below

    $d= ${env:ProgramFiles(x86)}
    tree $d

    But the problem is I have the folder address stored in a different variable (e.g., $x) and I don't know how create a ${$x}. There is Microsoft Doc and I read your article on 4SysOps too.


    Microsoft doc

    A little background of my project:

    I have an unresponsive security software that cannot be uninstalled from the control panel or the usual methods. One has to delete stuff manually- registry keys, folders and driver files. My approach to the problem was the following.

    1. Get the installLocation or uninstall key from registry
    $appString6432 = 'badSoftware'
    $reg6432 = 'HKLM:SoftwareWow6432NodeMicrosoftWindowsCurrentVersionUninstall*'
    $app6432 = Get-ItemProperty $reg6432 | Where-Object {$_.DisplayName -like $appString6432}
    $Path_app = $app6432.InstallLocation

    2. D0 a "tree" on $Path_app to find out the directory structure for that app. There is a nice way to achieve this on Mac.

    sudo pkgutil --only-dirs --files com.vendor.pkg.security-agent | more

    3. Proceed on manually removing them after the necessary NTFS permission tweaks

    It affected a large number of users. Therefore I was trying to do a script - dealing registry keys especially while remoting to users computers was a mess. So was going to individual folders and files.

  • Hi Swapnil,

    got it. You are right. If you notice the error on the tree, it somehow misses "c:"

     C:UsersRatandesktop> $p = "$env:programfiles(x86)"; tree $p
    Folder PATH listing for volume Windows
    Volume serial number is 2E3F-D6FD
    Invalid path - PROGRAM FILES(X86)      #<<<<<<<<<<<<<<<<
    No subfolders exist

    when one uses $v = "$Env:ProgramFiles(x86)", it will parse it as:

    C:UsersRatandesktop> $v = "$Env:ProgramFiles(x86)"; $v
    C:Program Files(x86)

    where as the actual folder is 'C:Program Files (x86)', that is the reason Test-Path is failing. If I try the string literal using '..' it does return true.

    C:UsersRatandesktop> $v = 'C:Program Files (x86)' ; Test-Path $v

    Something is wrong with the parsing. Setting it to a variable using


    as I did earlier works. But I am not sure how use the same for a variable.

  • PowerMe! liked comment of Swapnil Kambli on Free network performance monitoring with iPerf and PowerShell. (So far, Swapnil Kambli has 1 likes for this comment.) 1 year, 11 months ago

  • PowerMe! liked Integrating PuTTY in WinSCP. (So far, This post has 1 likes) 1 year, 11 months ago

  • Thanks for the article. I use  tcpdump in Linux. Recently I came across Windump, was not successful in running it- wonder if you have tried.

  • I guess one'd need more information.

    As I deal with web hosting, there are 2 ways:

    1. Host it on a server provided by the hosting provider
    2. Host it on your own server behind a firewall-router

    Case 1: There is just a registered public DNS record - universal for all users

    Case 2: One can create 2 DNS records- one for public and the other for internal users (although the latter is not required if you implement "hairpin NAT").

    Case 2 is similar to Mike's (Michael Pietroforte) suggestion above. I have an article elsewhere on that implementation.

  • Sorry as I posted it earlier in the wrong forum! Also, my apologies to Michael Pietroforte and

    Swapnil Kambli- I saw the messages late.

    The problem:

    $p = 'c:Program Files (86)'
    tree $p
    $p = "$env:ProgramFiles(x86)"
    tree $p

    would throw the following error.

    tree command

    Swapnil suggested to "have a test-path check before passing the control to tree command". Swapnil could you explain- did you mean some thing like if(test-path $p){....}  ?

    My experiment:

    $p = ${env:ProgramFiles(x86)} 
    tree $p

    tree command with folders with spaces

    However, I have to use a variable that gets the 'C:PROGRAM FILES (X86)' from a query from the registry. So I tried to simulate it as below.

    $pf86 = "$env:programfiles(x86)"
    $pf86 = ${$pf86}    # returns null
    tree $pf86          # prints the tree for the current folder

    The analogy with ${env:ProgramFiles(x86)} does not work- may be I am missing the syntax. I would love to hear.

  • Load More
© 4sysops 2006 - 2021


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account