Posted on September 5th, 2016
How can you tell whether an Active Directory domain controller is functioning properly? How do you know whether some over-zealous VLAN ACL is blocking necessary ports? Testing ICMP, is easy, just ping it. Testing LDAP response isn’t hard, I wrote a vbScript to do that years ago. But to complete, we want to check more. My list of things to check are this:
- TCP Ports 53,88,135,389,445,464
- UDP Ports 53,389,464
- If you are running NetBIOS add 139 TCP and UDP ports 137,138
- If the DNS port is open run NSLookup to check lookups
- If LDAP port is open, do a test bind
Since a large enterprise may have a large number of DCs, I wanted to multi-thread the script. For compatibility, I wanted to be able to run it on PowerShell 3 from a Windows 7 host without admin rights.
What I discovered is that testing TCP ports with PowerShell is pretty easy. UDP connections, however, turned out to be more difficult. After about 45 minutes of frustration, I found a great Test-Port function from PowerShell MVP Boe Prox. It is contained inside the script.
In my view, WorkFlows, introduced in Version 3, are the easiest way to multi-thread in PowerShell, and is a way which does not require special setup or rights on the remote systems. On my system, I see about 4 simultaneous queries using this method.
Test-DCs.ps1 can be edited to choose the testing of whatever ports you require and could easily be changed to test other systems such as web servers, Exchange or SharePoint servers.
Update 10-1-19: This version has many improvements, including multi-threading and dynamically determining whether query of DNS or GC ports is required.Script Text
Posted on June 26th, 2016
This was forwarded to me from one of our Microsoft guys. I have been using a batch file to fix WMI with this line for years: WMI: Stop hurting yourself by using “for /f %%s in (‘dir /s /b *.mof *.mfl’) do mofcomp %%s”
Posted on February 13th, 2016
I support a number of hospitals. Many of these have very large facilities, where the placement of computers was originally done by a space planner or others trying to make an educated guess about how and where people would be working. Frequently we find that there are computers which are unused or only rarely used. Efficient use of the machines requires that you identify these systems and reallocate them to be used where they are needed most.
There are a lot of ways to try to get at this information, for example, working with the information collected by SCCM, but you may not be collecting what is needed. I wanted to create a multi-threaded script which collected the list of users from AD, pinged the list, then recorded the most recent logon which was not done by the local administrator account.
Get-UnusedComputers.ps1 uses Get-WMIObject to find the local path of each of the user profiles. Because the “lastwritten” attribute is updated when you log on, I sort the files by that date to determine the most recent logon. The results are exported to your desktop in a CSV file.Script Text
Posted on February 13th, 2016
My friend, Nick Miller, has gone to work with another company, and is involved in a Windows 7 image standardization project. He recently told me that he had figured out how to have a single bootable USB WinPE disk to create both 32 bit and 64 bit OS images. Nick is a smart guy, and he had not found instructions for this anywhere else on the web. I suggested that he be my first Guest Blogger.
For a long time I have wanted to have a single USB bootable media that will install every Windows OS known to man. This has always eluded me because of the differences between architectures. Recently it bothered me to the point of fixing it.
If you have found this article, you probably already know how to build a WINPE 32 bit bootable media, and I will not bore you with the details. Start by creating a directory for the Windows 7 (32 bit) files. Create another directory for the Windows 7 (64 bit) file. For each OS architecture, create a Unattend.xml and place it inside the corresponding directory. It is important to note that both versions must be identical. For example, if you plan on deploying Windows 7 Professional (64 bit) you will need to start the Windows 7 Professional (32 bit) install process.
Here is where it gets mind numbing. Create a new unattend.xml called SpecialUnattend.xml (link has example file) with the WinPE phase of the x86, and the other 6 phases of the x64. Place this in the Windows 7 (64 bit) directory. Be sure to add the “Microsoft-Windows-Setup\Installimage\OSImage\InstallFrom\Path” in the Unattend.xml to point to the Windows 7 (64 bit) wim. IE. “D:\W764\Sources\Install.wim”. And last but not least, at the bottom of the Unattend.xml file (edited with notepad) make sure that the wim is correctly located when booted to the WinPE OS.
To execute, run the following example. “D:\W732\Sources\Setup.exe /InstallFrom:D:\W764\Sources\Install.wim /unattend:D:\W764\SpecialUnattend.xml”
Do not forget that the target drive will need to be wiped with diskpart.
For more information, feel free to reach out to me at NCSHREK on Hotmail.
Thanks Nick. I know that other SCCM admins will find this to be very helpful.
Posted on February 13th, 2016
Get-OldestEvent.ps1 is a PowerShell advanced function which returns the oldest event from a Windows computer event log, and will help you determine the rollover time for an event log by also returning the age of the record as a time span with the time created. Optionally you can return the entire oldest record with the age as an added member. Age is calculated from the time the script collects the information. You must, of course, have admin rights to query remote event logs. Running locally requires that PowerShell be run elevated. Because it is an advanced function, it must first be loaded with “dot sourcing”.
Example: Get the time created and age for the oldest event in the Security log of this computer.
Example: Get the time created and age for the oldest event in the Application log of this computer.
Get-OldestEvent -eLog Application
Example: Get the oldest event from the Security log on MyServerName, plus Age of event.
Get-OldestEvent -ComputerName MyServerName -eLog security -ReturnAll
Posted on September 7th, 2015
I discovered that my script to generate passwords, RandomPW.vbs, isn’t popular with users because the passwords are random. I have an even more complicated but unposted PowerShell version with the same issue.
I wanted to create something that was easier for the help desk and users. Get-TempPW.ps1 is my answer to those objections. This script is pretty well commented, so I won’t go into details about the code here. What the script does is get a randomly selected word from the web, capitalizes a random letter within the word, then appends numbers and special characters to the end. You can set the minimum word length and the number of numbers and special characters with variables within the code. The default is and eight character word plus a number and special character. The order of the numbers and special characters are randomized. An example password is “hypeRimmunization4&”.Script Text
Posted on September 7th, 2015
I have mentioned before that the Charlotte PowerShell User group was frequented by Scripting Guy Ed Wilson, and his wife Teresa. I’m sad to say that they have moved away, but am happy that Brian Wilhite has been running the meetings since. I mentioned to Brian that I had a cool way to get the parent container of an Active Directory object using ADSI:
$U = Get-ADUser $env:username
U = Get-ADUser $env:username
The string method is, of course faster. But If the parent object isn’t an OU, try the first method. It always works.
Posted on June 27th, 2015
Like most large enterprises, we use a group policies to manage Internet Explorer settings. We manage the security settings, and we enforce which sites are in Trusted Sites and the other internet zones. The user cannot change the list, or even view the list. This creates a problem for troubleshooting when a user has opened a ticket reporting that the website needs to be added to trusted sites. IT staff wants to know whether the site is already in the proper zone, and whether the GPO applied properly.
Get-IEZones.ps1 is a PowerShell script which will let you view the IE zone information from the local or a remote computer. The script uses the WMI accelerator instead of a registry cmdlet to read this data from the registry. Out-GridView displays the results which can be copied to your clipboard.Script Text
Posted on April 9th, 2015
Get-GroupHierarchy.ps1 gets a fully recursive listing of group membership. The script is based on a script by the same name posted at http://powershell.com/cs/forums/t/9588.aspx. I made a large number of changes to the original code. This script takes the SamAccountName of a group, such as Domain\MyGroupName, and then gives you all the members of the group. If a group is a member, it indents and gets the list of members of that group. Loops throw a warning.
It writes out a text log to your desktop. I used this code as the basis of a script which I used to fix a problem with a group used in SharePoint which had buried sub groups which were not mail enabled distribution groups. I’ll post that soon.
A tip of the hat to faithful reader, Bill P. He was really surprised when I called
Posted on March 9th, 2015
Remote Desktop Connection Manager 2.7, “manages multiple remote desktop connections. It is useful for managing server labs or large server farms where you need regular access to each machine such as automated check-in systems and data centers. It is similar to the built-in MMC Remote Desktops snap-in, but more flexible.” If you have been disappointed with Remote Desktops, then this bit of Microsoft freeware is what you want.
One of the nice things about the program is that it will import a list of server names. My vbscript, RDPhistory.vbs, will export the list of recent connections you have made using the Remote Desktop Connection application. Clean it up, and you have what you need to start.