Survey of domain computers, which are locked versus actively used

I would like to see who is working and who is not.

Is it possible to use software or a certain command to find all Windows 7/10 computers and notate which have the screen locked versus actively used?

Even better would be to log the information.

We run server 2012r2 with a single domain.

Thanks!
Eric BIT specialistAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Ben Personick (Previously QCubed)Lead SaaS Infrastructure EngineerCommented:
This would do the needful but would be a bit slow as it doesn't leverage parallelism:

$All_Systems = Get-ADComputer -Filter '*'-Properties OperatingSystem
$Desktops = $All_Systems | ?{$($_.Enabled) -eq $True  -and  $($_.OperatingSystem) -notMatch "Server"  } | Sort Name 

# $Win7_and_10 = $All_Systems | ?{ $($_.Enabled) -eq $True  -and ( $($_.OperatingSystem) -match "7" -or $($_.OperatingSystem) -match "10" ) }
$Desktops | Select Name, OperatingSystem, @{N="Locked_Status";e={[Bool](Get-Process "logonui" -ComputerName ($_.name))}} | FT 

Open in new window


Going to dump that into a workflow and see how it speeds up too.

Looks like its still a little slow due to timeout on systems that aren't there which we can probably resolve with test-connection



workflow Check-Locked {
    foreach -parallel ($Target in $Input) {
        $Target | Select Name, OperatingSystem, @{N="Locked_Status";e={[Bool](Get-Process "logonui" -ComputerName ($_.name))}}
    }
}


$All_Systems = Get-ADComputer -Filter '*'-Properties OperatingSystem
$Desktops = $All_Systems | ?{$($_.Enabled) -eq $True  -and  $($_.OperatingSystem) -notMatch "Server"  } | Sort Name 

# $Win7_and_10 = $All_Systems | ?{ $($_.Enabled) -eq $True  -and ( $($_.OperatingSystem) -match "7" -or $($_.OperatingSystem) -match "10" ) }

$Test = $All_Systems | ?{$($_.Enabled) -eq $True  -and  $($_.Name) -Match "R1Mgmthost"  } | Sort Name 
#$Test| Select Name, OperatingSystem, @{N="Locked_Status";e={[Bool](Get-Process "logonui" -ComputerName ($_.name))}}


$Desktops  | Check-Locked | FT 

Open in new window



Okay I added in some testing to see if the System are pingable first so we don;t bother with ones that arent.

workflow Check-Locked {
    foreach -parallel ($Target in $Input) {
        $Target | Select Name, OperatingSystem, @{N="Locked_Status";e={[Bool](Get-Process "logonui" -ComputerName ($_.DNSHostName))}}
    }
}

$($RDMZ_Systems_R2.DNSHostName) 
$All_Systems = Get-ADComputer -Filter '*'-Properties OperatingSystem

$Desktops = $All_Systems | ?{$($_.Enabled) -eq $True  -and  $($_.OperatingSystem) -notMatch "Server"  } | Sort Name 
$Desktops_Pingable = Test-Connection  $($Desktops.DNSHostName)  -asjob -count 4 | Get-Job | Receive-Job -Wait | Select-Object -unique -property Address, IPv4Address, @{Name='Reachable';Expression={[Bool](  $_.StatusCode -eq 0)}}| ? {$($_.Reachable) -eq $true} | Select-Object -unique -property Address, IPv4Address, Reachable

$Desktops_Reachable = $Desktops | ? {$($_.DNSHostName) -in $($Desktops_Pingable.Address)}

$Desktops_Reachable | Check-Locked | FT

Open in new window

Eric BIT specialistAuthor Commented:
I like how you're thinking.  Good idea with ping also.

Sorry - I'm an 80's batch file guy- would you mind giving you step-by-step on launching this?  


I'm the administrator....could I also schedule something to run at the workstations every 15 min and use tasklist or other to write out data to a log file?
Ben Personick (Previously QCubed)Lead SaaS Infrastructure EngineerCommented:
I'm a CMD Script guy myself, I've only truely started to move to powershell i earnest in the last couple of years.

The Script does the followisng:

1) Connect to AD and grab a list of Computers, along with their OS Name Property
2) Filters that list into Computers that do not have  Server operating System
3) Pings the DNS name of all Systems and creates a list fo the Systems which responded
4) Filters the List of Computer objects from AD by the pingable ones. - Note  I am having some problems with that object because it's not giving me a simple array I need to amend it, removing this step for now.
5) Calls a Powershell Workflow which allows us to loop the computer objects in Parallel to check them.
6) From each object it selects the Name of the System and runs a remote Powershell query to the system to see if the Lock Screen UI process is running (it only runs when a system is locked on the CONSOLE - RDP Sessions will not stop it from running)
7) It reports back that info and is formatted into a table for output.

You can schedule it to run via task scehduler by wrapping the Powershell in a batch.

 Run it in our environment by hand first and make sure how quickly it responds for you, as its going to be slow if there are systems which it has trouble connecting to.


workflow Check-Locked {
    foreach -parallel ($Target in $Input) {
        $Target | Select Name, OperatingSystem, @{N="Locked_Status";e={[Bool](Get-Process "logonui" -ComputerName ($_.DNSHostName))}}
    }
}

$($RDMZ_Systems_R2.DNSHostName) 
$All_Systems = Get-ADComputer -Filter '*'-Properties OperatingSystem

$Desktops = $All_Systems | ?{$($_.Enabled) -eq $True  -and  $($_.OperatingSystem) -notMatch "Server"  } | Sort Name 
$Desktops_Pingable = Test-Connection  $($Desktops.DNSHostName)  -asjob -count 4 | Get-Job | Receive-Job -Wait | Select-Object -unique -property Address, IPv4Address, @{Name='Reachable';Expression={[Bool](  $_.StatusCode -eq 0)}}| ? {$($_.Reachable) -eq $true} | Select-Object -unique -property Address, IPv4Address, Reachable

$Desktops_Reachable = $Desktops <# ## Removed for now. ### | ? {$($_.DNSHostName) -in $($Desktops_Pingable.Address)} #>

$Desktops_Reachable | Check-Locked | FT

Open in new window

Angular Fundamentals

Learn the fundamentals of Angular 2, a JavaScript framework for developing dynamic single page applications.

Eric BIT specialistAuthor Commented:
Thank you for explaining how it works, you have spent a lot of time on this.

I honestly need help running it-I saved it as locked.ps1 and tried running from File Explorer -  I get a black box flash by with red text and the window goes away.
Ben Personick (Previously QCubed)Lead SaaS Infrastructure EngineerCommented:
You can't just run a PS1 file.

You should check this in Powershell ISE and see what is up, and you need to run this from a System which has the Active Directory Tools Installed.

I can write a CMD wrapper version of the file which you can run from the CMD Prompt and auto-elevates, and auto calls Powershell, but you should be testing in Powershell ISE first to make sure we take care of the prereqs to run the script.

You can paste this script into Powershell ISE and run it for testing, and you can paste it into a .CMD script and run it for real.

 The CMD portion is commented out for the powershell interpreter, and the Powershell Portion is similarly ignored by CMD.

<# ## & REM Script: CheckLocked.CMD  --  Wrapper CMD Script to Run Powershell.
	@(
		SETLOCAL ENABLEDELAYEDEXPANSION
		ECHO OFF
		ECHO. Testing For Elevated Command Prompt...
		(
			NET SESSION 2>&1 >NUL
		) || (
		ECHO.Elevated Command Prompt Not detected, launching batch again in elevated command prompt.
		ECHO. If you are prompted by UAC, accept.
		ECHO. Original batch Script will exit without running further.
		ECHO. CreateObject^("Shell.Application"^).ShellExecute "%~0", "", "", "runas", 1 >"%temp%\runas.vbs"
	  "%temp%\runas.vbs"
		PAUSE
		GOTO :EOF
		)
		COLOR 27
	)
	ECHO.  This Script is Now Executing Code in an Elevated CMD Prompt!
	ECHO.
	@( 
		SETLOCAL ENABLEDELAYEDEXPANSION
		Echo Off
		SET "_eLvl=0"
		IF EXIST "%~dpn0.ps1" (
			DEL /Q /F %~dpn0.ps1"
		)
		MKLINK /H "%~dpn0.ps1" "%~f0"
	)

	Call :Main %*

	(
	  ENDLOCAL
	  EXIT /B %_eLvl%
	)

	:Main
	ECHO. CMD: %~n0: Found the Following Arguments and will Process them:
	ECHO. CMD: [%*]
		for %%A IN (%*) DO (
			REM  Alternative:  Call self as Powershell script passing a file as an argument.
			ECHO.
			ECHO.CMD: Processing File %%A
			Powershell.exe -ExecutionPolicy Bypass -File "%~dpn0.ps1" %%A
		)
	PAUSE
	GOTO :EOF
	REM. Powershell Portion follows
#>

## Script: CheckLocked.ps1
## Powershell Portion Begins

## import Modules and other house keeing just in case needed

set-executionpolicy unrestricted

Set-PSRepository -Name 'PSGallery' -InstallationPolicy Trusted
Install-WindowsFeature RSAT-AD-PowerShell
Install-Module -Name WindowsCompatibility
Import-Module -Name WindowsCompatibility
Import-Module ActiveDirectory


workflow Check-Locked {
    foreach -parallel ($Target in $Input) {
        $Target | Select Name, OperatingSystem, @{N="Locked_Status";e={[Bool](Get-Process "logonui" -ComputerName ($_.DNSHostName))}}
    }
}

$All_Systems = Get-ADComputer -Filter '*'-Properties OperatingSystem

$Desktops = $All_Systems | ?{$($_.Enabled) -eq $True  -and  $($_.OperatingSystem) -notMatch "Server"  } | Sort Name 
$Desktops_Pingable = Test-Connection  $($Desktops.DNSHostName)  -asjob -count 4 | Get-Job | Receive-Job -Wait | Select-Object -unique -property Address, IPv4Address, @{Name='Reachable';Expression={[Bool](  $_.StatusCode -eq 0)}}| ? {$($_.Reachable) -eq $true} | Select-Object -unique -property Address, IPv4Address, Reachable

$Desktops_Reachable = $Desktops <# ## Removed for now. ### | ? {$($_.DNSHostName) -in $($Desktops_Pingable.Address)} #>

$Desktops_Reachable | Check-Locked | FT

Open in new window

Eric BIT specialistAuthor Commented:
Awesome, thanks!   I will install the toolkit and the Powershell ISE and give it a shot... Might not be today though.
Ben Personick (Previously QCubed)Lead SaaS Infrastructure EngineerCommented:
ISE is installed by default in windows.

You may need to update powershell.

I suggest always running scripting from a dedicated management VM running windows server so you can freely work wirh it and scripts arent tied to your own machine as you'll usually be able to have more admin tools at your fingertips there ans add or remove any as needed without interrupting tour own workstation and possibly rebooting or having that cause you some issues.

In the above I also added the powershell code to try to install some of the features but it was just a guess as it can change depending on version of windows.
Eric BIT specialistAuthor Commented:
Logonui was a good clue.

I am tinkering with WMIC

wmic /node:pcname process where name="logonui.exe"
Ben Personick (Previously QCubed)Lead SaaS Infrastructure EngineerCommented:
Okay just tested and it wasn't calling the PowerShell because I took the code for that from another script to make it a CMD Wrapper and didn't have time to test.  I just had;t heard back so I didn't think to check.

I am using the Powershell method to check processes, but I can change that to the Powershell method to check WMIC and query the processes that way, if that would be better in your environment.

  But I am just going to post the working script and the example of it running for now.

Copy the following script and save as CheckLocked.CMD

it will automatically run the inner PowerShell for you.

 I have updated the code and shown it working on my systems.
<# ## & REM Script: CheckLocked.CMD  --  Wrapper CMD Script to Run Powershell.
	@(
		SETLOCAL ENABLEDELAYEDEXPANSION
		ECHO OFF
		ECHO. Testing For Elevated Command Prompt...
		(
			NET SESSION 2>&1 >NUL
		) || (
			ECHO.Elevated Command Prompt Not detected, launching batch again in elevated command prompt.
			ECHO. If you are prompted by UAC, accept.
			ECHO. Original CMD Script will exit without running further.
			powershell.exe -Command "Start-Process cmd \"/k %~dpnx0\" -Verb RunAs"
			GOTO :EOF
		)
		COLOR 27
	)
	ECHO.  This Script is Executing Code in an Elevated CMD Prompt!
	ECHO.
	@( 
		SETLOCAL ENABLEDELAYEDEXPANSION
		Echo Off
		SET "_eLvl=0"
		IF EXIST "%~dpn0.ps1" (
			DEL /Q /F %~dpn0.ps1"
		)
		MKLINK /H "%~dpn0.ps1" "%~f0"
	)

	Call :Main %*

	(
	  ENDLOCAL
	  EXIT /B %_eLvl%
	)

	:Main
		ECHO."CMD: Calling Powershell Portion of Script."
		Powershell.exe -ExecutionPolicy unrestricted -File "%~dpn0.ps1" %%A

	PAUSE
	GOTO :EOF
	REM. Powershell Portion follows
#>

## Script: CheckLocked.ps1
## Powershell Portion Begins

## import Modules and other house keeing just in case needed
"

Powershell Started"
set-executionpolicy unrestricted

Set-PSRepository -Name 'PSGallery' -InstallationPolicy Trusted
Install-WindowsFeature RSAT-AD-PowerShell
Install-Module -Name WindowsCompatibility
Import-Module -Name WindowsCompatibility
Import-Module ActiveDirectory


workflow Check-Locked {
    foreach -parallel ($Target in $Input) {
        $Target | Select Name, OperatingSystem, @{N="Locked_Status";e={[Bool](Get-Process "logonui" -ComputerName $($_.DNSHostName))}}
    }
}

$All_Systems = Get-ADComputer -Filter '*'-Properties OperatingSystem

$Desktops = $All_Systems | ?{$($_.Enabled) -eq $True  -and  $($_.OperatingSystem) -notMatch "Server"  -and  $($_.DNSHostName) -ne $NULL  } | Sort Name 
$Desktops_Pingable = Test-Connection  $($Desktops.DNSHostName)  -asjob -count 4 | Get-Job | Receive-Job -Wait | Select-Object -unique -property Address, IPv4Address, @{Name='Reachable';Expression={[Bool](  $_.StatusCode -eq 0)}}| ? {$($_.Reachable) -eq $true} | Select-Object -unique -property Address, IPv4Address, Reachable

$Desktops_Reachable = $Desktops <# ## Removed for now. ### | ? {$($_.DNSHostName) -in $($Desktops_Pingable.Address)} #>

$Desktops_Reachable | Check-Locked | FT

Open in new window

2019-05-17-19_48_50-10.10.173.1---Re.png

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Eric BIT specialistAuthor Commented:
Thanks for all your time on this!
Ben Personick (Previously QCubed)Lead SaaS Infrastructure EngineerCommented:
Glad to help!  :)
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Software

From novice to tech pro — start learning today.