Perform a couple actions on PC's listed in text file

Hey Experts.  Trying my hand at a script that will clean-up profiles on the Windows 7 pc's in our training lab.  

I thought a script that pulled the computer names from the OU, put them in a text file and then perform a few actions on each pc in that file while recording the failure/success of the actions.  Something like A) ping the pc's to see if they are online and B) remove profiles. I put together a starting script but struggled with the profiles being removed from the computers that are pingable.

Get-ADComputer -Filter 'Name -like "TRN3*"' -SearchBase "OU=COMPUTERS,OU=TRAINING,OU=DEPTS,DC=LOCAL" -Property * | Select-Object name | out-file c:\tools\logs\output.txt

get-content -path c:\tools\logs\output.txt | foreach-object { ping $_ } > c:\tools\logs\pingresult.txt

Open in new window


End goal: powershell script that creates a logfile of computer names from the OU specified, verifies the computer is online via ping and if it is, removes the user profiles on each computer listed in the logfile.  Logging results to verify success.  

Again, any constructive criticism is welcome and I appreciate your time.

(edited for clarification)
LVL 9
samiam41Asked:
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.

samiam41Author Commented:
Still tweaking this and welcome a more tested script you may have

Get-ADComputer -Filter 'Name -like "TRN3*"' -SearchBase "OU=COMPUTERS,OU=TRAINING,OU=DEPTS,DC=LOCAL" -Property * | Select-Object -ExpandProperty name | out-file c:\tools\logs\testlog.csv

$TrainingPC = Get-Content "c:\tools\logs\testlog.csv" 
    ForEach ($computer in $TrainingPC)
        { 
          if (Test-Connection -ComputerName $computer -Count 1 -ErrorAction SilentlyContinue){
    Write-Host "$computer,up"
    gwmi win32_logicaldisk -ComputerName $computer -Filter "DeviceID='C:'" | Format-Table DeviceId, MediaType, @{n="Size";e={[math]::Round($_.Size/1GB,2)}},@{n="FreeSpace";e={[math]::Round($_.FreeSpace/1GB,2)}}
  }
  else{
    Write-Host "$computer,down"
    }

Open in new window

Michael PfisterCommented:
Instead of gwmi win32_logicaldisk use

gwmi -class Win32_UserProfile | Where { $_.SID.Length -gt 8 -and $_.Sid.Substring($_.Sid.Length-
5,4) -ne '-100'}  (gwmi -class Win32_UserProfile  -ComputerName $computer '").Delete()

Open in new window


Bit tricky to filter out local Windows internal like NetworkService profiles and the defaultuser profile.. test before running live.
Michael PfisterCommented:
As an alternative you can list the SIDs of your users, then filter to get only the domain users
:

 gwmi -class Win32_UserProfile -Computer "TargetComputer" | Where { $_.SID -like "your domain sid starts with%"} 

Open in new window

List local profiles

 
gwmi -class Win32_UserProfile -Computer "TargetComputer" |select sid,localpath

Open in new window



Hth
Exploring ASP.NET Core: Fundamentals

Learn to build web apps and services, IoT apps, and mobile backends by covering the fundamentals of ASP.NET Core and  exploring the core foundations for app libraries.

oBdACommented:
This should do the trick.
It will skip system profiles, profiles that are still loaded, and the default administrator's profile.
It's in test mode and will only show what it would delete; uncomment line 12 ("#  [void]$_.Delete()") to run it for real:
$computerList = Get-Content C:\Temp\computerlist.txt
$logFile = 'C:\Temp\profiles.csv'
$computerList | ForEach-Object {
	$computerName = $_
	Write-Host "Processing $($computerName) ..."
	If (Test-Connection -ComputerName $computerName -Count 2 -Quiet) {
		Try {
			$profiles = Get-WmiObject -Class Win32_UserProfile -Filter "(Special='False') And (Loaded='False') And (Not (SID Like '%500'))" -ComputerName $computerName -ErrorAction Stop
			If ($profiles) {
				$profiles | ForEach-Object {
					$out = $_ | Select-Object -Property @{n='ComputerName'; e={$computerName}}, SID, LocalPath, RoamingConfigured, RoamingPath, Result
					Try {
#						[void]$_.Delete()
						$out.Result = "Profile deleted"
					} Catch {
						$out.Result = "ERROR: $($_.Exception.Message)"
					}
					$out
				}
			} Else {
				[PSCustomObject]@{ComputerName=$computerName; Result='Found no profiles to delete'}
			}
		} Catch {
			[PSCustomObject]@{ComputerName=$computerName; Result="ERROR: $($_.Exception.Message)"}
		}
	} Else {
		[PSCustomObject]@{ComputerName=$computerName; Result='No ping response'}
	}
} | Select-Object -Property ComputerName, SID, LocalPath, RoamingConfigured, RoamingPath, Result | Export-Csv -NoTypeInformation -Path $logFile

Open in new window

samiam41Author Commented:
Thanks Experts!  Running through the suggestions now and will report back asap
samiam41Author Commented:
oBdA, brilliant work as always!  I was curious how to capture the drive space before/after the profiles are wiped out.  I had this portion of code but wasn't sure where to inject with the code you provided.  

gwmi win32_logicaldisk -ComputerName $computer -Filter "DeviceID='C:'" | Format-Table DeviceId, MediaType, @{n="Size";e={[math]::Round($_.Size/1GB,2)}},@{n="FreeSpace";e={[math]::Round($_.FreeSpace/1GB,2)}}

Open in new window

samiam41Author Commented:
@Michael Pfister, thank you for the coding.  I'm testing it once I wrap up the suggestion from oBdA.
oBdACommented:
Like this, for example; it'll add a separate row with a disk summary in the Results column once it's done with each computer.
$computerList = Get-Content C:\Temp\computerlist.txt
$computerList | ForEach-Object {
	$computerName = $_
	Write-Host "Processing $($computerName) ..."
	If (Test-Connection -ComputerName $computerName -Count 2 -Quiet) {
		Try {
			$diskC = Get-WmiObject  Win32_LogicalDisk -Filter "DeviceID='C:'" -ComputerName $computerName -ErrorAction SilentlyContinue
			$diskSize = [math]::Round($diskC.Size / 1GB, 2)
			$freeSpaceBefore = [math]::Round($diskC.FreeSpace / 1GB, 2)
			$profiles = Get-WmiObject -Class Win32_UserProfile -Filter "(Special='False') And (Loaded='False') And (Not (SID Like '%500'))" -ComputerName $computerName -ErrorAction Stop
			If ($profiles) {
				$profiles | ForEach-Object {
					$out = $_ | Select-Object -Property @{n='ComputerName'; e={$computerName}}, SID, LocalPath, RoamingConfigured, RoamingPath, Result
					Try {
#						[void]$_.Delete()
						$out.Result = "Profile deleted"
					} Catch {
						$out.Result = "ERROR: $($_.Exception.Message)"
					}
					$out
				}
			} Else {
				[PSCustomObject]@{ComputerName=$computerName; Result='Found no profiles to delete'}
			}
			$diskC = Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='C:'" -ComputerName $computerName -ErrorAction SilentlyContinue
			$freeSpaceAfter = [math]::Round($diskC.FreeSpace / 1GB, 2)
			[PSCustomObject]@{ComputerName=$computerName; Result="SUMMARY: disk size $($diskSize)GB, free space before: $($freeSpaceBefore)GB, free space after: $($freeSpaceAfter)GB"}
		} Catch {
			[PSCustomObject]@{ComputerName=$computerName; Result="ERROR: $($_.Exception.Message)"}
		}
	} Else {
		[PSCustomObject]@{ComputerName=$computerName; Result='No ping response'}
	}
} | Select-Object -Property ComputerName, SID, LocalPath, RoamingConfigured, RoamingPath, Result 

Open in new window

samiam41Author Commented:
Amazing script but I didn't see where the log file is listed now.
oBdACommented:
Temporary removal for testing ...
$computerList = Get-Content C:\Temp\computerlist.txt
$logFile = 'C:\Temp\profiles.csv'
$computerList | ForEach-Object {
	$computerName = $_
	Write-Host "Processing $($computerName) ..."
	If (Test-Connection -ComputerName $computerName -Count 2 -Quiet) {
		Try {
			$diskC = Get-WmiObject  Win32_LogicalDisk -Filter "DeviceID='C:'" -ComputerName $computerName -ErrorAction SilentlyContinue
			$diskSize = [math]::Round($diskC.Size / 1GB, 2)
			$freeSpaceBefore = [math]::Round($diskC.FreeSpace / 1GB, 2)
			$profiles = Get-WmiObject -Class Win32_UserProfile -Filter "(Special='False') And (Loaded='False') And (Not (SID Like '%500'))" -ComputerName $computerName -ErrorAction Stop
			If ($profiles) {
				$profiles | ForEach-Object {
					$out = $_ | Select-Object -Property @{n='ComputerName'; e={$computerName}}, SID, LocalPath, RoamingConfigured, RoamingPath, Result
					Try {
#						[void]$_.Delete()
						$out.Result = "Profile deleted"
					} Catch {
						$out.Result = "ERROR: $($_.Exception.Message)"
					}
					$out
				}
			} Else {
				[PSCustomObject]@{ComputerName=$computerName; Result='Found no profiles to delete'}
			}
			$diskC = Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='C:'" -ComputerName $computerName -ErrorAction SilentlyContinue
			$freeSpaceAfter = [math]::Round($diskC.FreeSpace / 1GB, 2)
			[PSCustomObject]@{ComputerName=$computerName; Result="SUMMARY: disk size $($diskSize)GB, free space before: $($freeSpaceBefore)GB, free space after: $($freeSpaceAfter)GB"}
		} Catch {
			[PSCustomObject]@{ComputerName=$computerName; Result="ERROR: $($_.Exception.Message)"}
		}
	} Else {
		[PSCustomObject]@{ComputerName=$computerName; Result='No ping response'}
	}
} | Select-Object -Property ComputerName, SID, LocalPath, RoamingConfigured, RoamingPath, Result | Export-Csv -NoTypeInformation -Path $logFile

Open in new window

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
samiam41Author Commented:
Thanks Experts for your help with this project!  I always learn so much from you all when you contribute.
samiam41Author Commented:
If any of you have time for this question, I'd appreciate your help.

https://www.experts-exchange.com/questions/29142460/Include-details-into-log-file.html
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
Powershell

From novice to tech pro — start learning today.