PowerShell get output in CSV format - powershell

I am seeking help to get output in csv format. I have written powershell code and would want to tweak the output to get in csv format as shown in below pic.
$servers = Get-Content 'C:\Temp\listofservers.txt'
foreach ($server in $servers)
{
#DHCP
if (((Get-Service -ComputerName $server -ServiceName 'DHCPServer' -ErrorAction SilentlyContinue).Status) -eq 'Running')
{
if ((((Get-DhcpServerv4Scope -ComputerName $server | Get-DhcpServerv4Lease -ComputerName $server) | Measure-Object).Count) -ge 1)
{
Write-Host "DHCP present on $server and in use"
}
else
{
Write-Host "DHCP present on $server and not in use"
}
}
else
{
Write-Host("DHCP is not present on $server")
}
#Certificate authority
if (((Get-Service -ComputerName $server -ServiceName 'CertSvc' -ErrorAction SilentlyContinue).Status) -eq 'Running')
{
Write-Host "Certificate Authority is present on $server"
}
else
{
Write-Host "Certificate Authority is not present on $server"
}
}

Send all outputs to a custom object then export them:
$servers = get-content "C:\Temp\listofservers.txt"
$ExportPath = 'c:\temp\results.csv'
$Servers | ForEach-Object {
Write-Host "Checking $_"
# DHCP status
# Use Try....Catch to trap the errors - it's more robust than
# If...Then and prevents a wall of red text if something goes wrong
Try {
$DHCPStatus = Get-Service -ComputerName $_ -Name 'DHCPServer' -ErrorAction Stop
If ($DHCPStatus.Status -eq "Running") {
Try {
If ((((Get-DhcpServerv4Scope -ComputerName $_ -ErrorAction Stop | Get-DhcpServerv4Lease -ComputerName $_ -ErrorAction Stop) | Measure-Object).Count) -ge 1) {
$DHCPResult = "DHCP present on, in use"
}
Else {
$DHCPResult = "DHCP present, not in use"
}
}
Catch {
$DHCPResult = "DHCP present - error obtaining details: $_"
}
}
}
Catch {
$DHCPResult = "DHCP is not present"
}
#Certificate authority
Try {
If (((Get-Service -ComputerName $_ -ServiceName 'CertSvc' -ErrorAction Stop).Status) -eq "Running") {
$CAResult = "Certificate Authority is present"
}
}
Catch {
$CAResult = "Certificate Authority is not present"
}
[pscustomobject]#{ComputerName = $_;DHCP = $DHCPResult;CA=$CAResult}
} | Export-Csv -Path $ExportPath -NoTypeInformation

Use a hashtable to build your object, adding key/values for each property along the way. Then convert the hashtable to a [PSCustomObject] and output it capturing in a variable ($results). Finally, export it to csv using Export-Csv
$servers = Get-Content 'C:\Temp\listofservers.txt'
$results = foreach ($server in $servers) {
# Create hashtable to build object and add ComputerName property
$output = [ordered]#{ComputerName = $server }
#DHCP
if (((Get-Service -ComputerName $server -ServiceName 'DHCPServer' -ErrorAction SilentlyContinue).Status) -eq 'Running') {
if ((((Get-DhcpServerv4Scope -ComputerName $server |
Get-DhcpServerv4Lease -ComputerName $server) |
Measure-Object).Count) -ge 1) {
# add Dhcp property if present, in use
$output.Add('Dhcp', 'Present, in use')
}
else {
# add Dhcp property if present, not in use
$output.Add('Dhcp', 'Present, not in use')
}
}
else {
# add Dhcp property if not present
$output.Add('Dhcp', 'Not present')
}
#Certificate authority
if (((Get-Service -ComputerName $server -ServiceName 'CertSvc' -ErrorAction SilentlyContinue).Status) -eq 'Running') {
# add CA property if present
$output.Add('CA', 'Present')
}
else {
# add CA property if not present
$output.Add('CA', 'Not present')
}
# Convert hashtable to pscustomobject and output it
[PSCustomObject]$output
}
# output results to screen
$results
# export results to csv file
$results | Export-Csv -Path c:\temp\server_dhcp_ca_check.csv -NoTypeInformation

Related

Powershell Error Handling not working in Invoke-command block

I want to print error message when service is not found or machine is offline
$csv = Import-Csv "C:\Users\user\Desktop\computers.csv" -delimiter ","
foreach ($cs in $csv){
$computers = $cs.DNSHostname
foreach ($computer in $computers){
Try{
Invoke-Command -ComputerName $computer -ScriptBlock {
$ProcessCheck = Get-Process -Name agentid-service -ErrorAction Stop
if ($null -eq $ProcessCheck) {
Write-output "agentid-service IS not running $env:computername"
}
else {
Write-output "agentid-service IS running $env:computername"
}
}
}
catch{
Write-Warning $Error[0]
}
}
}
Instead, when service name is not found, i'm getting error:
Cannot find a process with the name "agentid-service". Verify the process name and call the cmdlet again.
And if connection to computer is not possible then getting:
[vm.domain.local] Connecting to remote server vm.domain.local failed with the following error message : The WinRM client cannot process the request because the server name cannot be resolved.
And script continue execution (as it should).
How can i get "Catch" block to be executed ?
You can do this in one foreach loop.
Try
$computers = (Import-Csv "C:\Users\user\Desktop\computers.csv").DNSHostname
foreach ($computer in $computers) {
if (!(Test-Connection -ComputerName $computer -Count 1 -Quiet)) {
Write-Warning "Computer $computer cannot be reached"
continue # skip this one and proceed with the next computer
}
try{
Invoke-Command -ComputerName $computer -ScriptBlock {
$ProcessCheck = Get-Process -Name 'agentid-service' -ErrorAction Stop
if (!$ProcessCheck.Responding) {
"agentid-service is NOT not running on computer '$env:computername'"
}
else {
"agentid-service is running on computer '$env:computername'"
}
}
}
catch{
Write-Warning $_.Exception.Message
}
}
Thanks to #Theo's answer, managed to fix it:
$csv = Import-Csv "C:\Users\user\Desktop\computers.csv" -delimiter ","
foreach ($cs in $csv){
$error.Clear()
$computers = $cs.DNSHostname
foreach ($computer in $computers){
Try{
Invoke-Command -ComputerName $computer -ScriptBlock {
$ProcessCheck = Get-Process -Name agentid-service -ErrorAction Stop
if ($null -ne $ProcessCheck) {
Write-output "agentid-service IS running $env:computername"
}
} -ErrorAction Stop
}
catch{
if ($null -eq $ProcessCheck){
Write-warning "agentid-service IS not running $env:computername"
}
Write-Warning $Error[0]
}
}
}

Detect SMB1 version via powershell for all OSes

My workflow:
check if server is pingable
find if they are domain connected or not and perform a task accordingly. if Operating system 2012 and/or R2 ,2016 or 2019 newer OSes then I will run Get-SmbServerConfiguration cmdlet. if machine is not a part of default domain then else block will run.
if Operating system 2003 or 2008 oldest OSes then I will run Get-Wmi cmdlet. if machine is not a part of default domain then else block will run.
Finally , I will concentanate $results variable.
My question is :
1- How can we get remotely regedit value for 2003 or 2008 oldest OSes IS NOT a part of default domain insie else block?
Also , Condition will be like below.
if SMB1 value is "0" then result will be `false`
if SMB1 value is "1" then result will be `true`
if SMB1 value is not exist then result will be `not exist value`
2- How can I create object properties $SMBAudit variable ? because , I will concentanate all outputs inside $results variable.
$reg = [wmiclass]"\\$computer\root\default:StdRegProv"
$SMBAudit = $reg.GetStringValue($basekey, $subkey, $value).sValue
My desired output :
Computername,SMB1Enabled
Host01,True
Host02,False
I will write so far a script like below. but I am stucking somethings.
Script :
# Computer List
$allComputers = Get-Content .\path\to\computers.txt
read-host -assecurestring | convertfrom-securestring | out-file C:\mysecurestring_domain.txt
read-host -assecurestring | convertfrom-securestring | out-file C:\mysecurestring_local.txt
# Create empty array of results
$Results = #()
# Loop through computers
foreach($computer in $allComputers) {
# check if server is pingable before running the query on the server
if (Test-Connection $computer -Count 1 -Quiet) {
Write-Host "`n`n$computer is online!" -BackgroundColor Green -ForegroundColor Black
}
if(Get-ADComputer -Filter {Name -eq $computer -and OperatingSystem -notlike '*Windows*Server*2003*' -and OperatingSystem -notlike '*Windows*Server*2008*'})
{
#"machine $_ is a part of default domain"
# The command we want to run
$username = "domain01\admin01"
$password = Get-Content 'C:\mysecurestring_domain.txt' | ConvertTo-SecureString
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $password
$SMB = Invoke-Command -ComputerName $computer -Credential $cred -ScriptBlock {Get-SmbServerConfiguration | Select EnableSMB1Protocol }
# Create properties
$Properties = #{
# Populate the properties "Computername" and "SMB1Enabled" with variables
Computername = $Computer
SMB1Enabled = $SMB.EnableSMB1Protocol
}
# Add the properties to the result for each object
$Results += New-Object psobject -Property $Properties
}
else
{
#"machine $_ IS NOT a part of default domain"
$username = "localadmin01"
$password = Get-Content 'C:\mysecurestring_local.txt' | ConvertTo-SecureString
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $password
$SMB = Invoke-Command -ComputerName $computer -Credential $cred -ScriptBlock {Get-SmbServerConfiguration | Select EnableSMB1Protocol }
# Create properties
$Properties = #{
# Populate the properties "Computername" and "SMB1Enabled" with variables
Computername = $Computer
SMB1Enabled = $SMB.EnableSMB1Protocol
}
# Add the properties to the result for each object
$Results += New-Object psobject -Property $Properties
}
# Oldest OSes
if(Get-ADComputer -Filter {Name -eq $computer -and OperatingSystem -notlike '*Windows*Server*2012*' -and OperatingSystem -notlike '*Windows*Server*2016*' -and OperatingSystem -notlike '*Windows*Server*2019*'})
{
#"machine $_ is a part of default domain"
# The command we want to run
<# HKEY_CLASSES_ROOT (2147483648 (0x80000000))
HKEY_CURRENT_USER (2147483649 (0x80000001))
HKEY_LOCAL_MACHINE (2147483650 (0x80000002))
HKEY_USERS (2147483651 (0x80000003))
HKEY_CURRENT_CONFIG (2147483653 (0x80000005))
#>
$basekey = [uint32]'0x80000002'
$subkey = 'SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters'
$value = 'SMB1'
$reg = [wmiclass]"\\$computer\root\default:StdRegProv"
$SMBAudit = $reg.GetStringValue($basekey, $subkey, $value).sValue
}
else
{
#"machine $_ IS NOT a part of default domain"
}
# Output
$Results | Select-Object Computername, SMB1Enabled | Out-File -Filepath c:\temp\smb1-computers.txt
I think you are over complicating this and although not tested by me, you could try this:
# Computer List
$allComputers = Get-Content '.\path\to\computers.txt'
# get credentials for domain-joined machines and for local machines
$domainCred = Get-Credential -UserName "domain01\admin01" -Message "Please enter the DOMAIN password"
$localCred = Get-Credential -UserName "localadmin01" -Message "Please enter the LOCAL password"
# loop through the list of computers and collect output in variable $Results
$Results = foreach($computer in $allComputers) {
# check if server is pingable before running the query on the server
if (Test-Connection -ComputerName $computer -Count 1 -Quiet) {
Write-Host "$computer is online!" -BackgroundColor Green -ForegroundColor Black
$server = Get-ADComputer -Filter "Name -eq '$computer'" -Properties OperatingSystem -ErrorAction SilentlyContinue
# if domain joined, use $domainCred, otherwise $localCred
if ($server) {
$cred = $domainCred
$version = ([regex]'Windows Server (\d+)').Match($server.OperatingSystem).Groups[1].Value
}
else {
$cred = $localCred
$info = Get-WmiObject -ComputerName $computer -Credential $cred -Class Win32_OperatingSystem
$version = ([regex]'Windows Server (\d+)').Match($info.Caption).Groups[1].Value
}
if ($version -eq '2003') {
# try reading the registry
try {
$RegBase = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Computer)
$RegKey = $RegBase.OpenSubKey("SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters")
$SMB = $RegKey.GetValue("SMB1")
[PsCustomObject]#{ ComputerName = $computer; SMB1Enabled = ($null -eq $SMB -or [int]$SMB -eq 1) }
}
catch {
[PsCustomObject]#{ ComputerName = $computer; SMB1Enabled = 'Could not read Remote Registry' }
}
finally {
if ($RegBase) { $RegBase.Close() }
if ($RegKey) { $RegKey.Close() }
}
}
elseif ($version -eq '2008') {
# Older OS
try {
# try via WinRM
$SMB = Invoke-Command -ComputerName $computer -Credential $cred -ScriptBlock {
Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters' -Name SMB1
} -ErrorAction Stop
# output an object
[PsCustomObject]#{ ComputerName = $computer; SMB1Enabled = ($null -eq $SMB -or [int]$SMB -eq 1) }
}
catch {
# try reading the registry
try {
$RegBase = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Computer)
$RegKey = $RegBase.OpenSubKey("SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters")
$SMB = $RegKey.GetValue("SMB1")
[PsCustomObject]#{ ComputerName = $computer; SMB1Enabled = ($null -eq $SMB -or [int]$SMB -eq 1) }
}
catch {
[PsCustomObject]#{ ComputerName = $computer; SMB1Enabled = 'Could not read Remote Registry' }
}
finally {
if ($RegBase) { $RegBase.Close() }
if ($RegKey) { $RegKey.Close() }
}
}
}
else {
# Newer OS
$SMB = Invoke-Command -ComputerName $computer -Credential $cred -ScriptBlock { Get-SmbServerConfiguration | Select-Object EnableSMB1Protocol }
# output an object
[PsCustomObject]#{ ComputerName = $computer; SMB1Enabled = $SMB.EnableSMB1Protocol }
}
}
else {
Write-Warning "Computer $computer is off-line"
# output an object anyway, so that in the CSV it is known that the computer didn't ping
[PsCustomObject]#{ ComputerName = $computer; SMB1Enabled = 'Off-Line' }
}
}
# Output on screen
$Results | Format-Table -AutoSize
# Output to CSV file
$Results | Export-Csv -Path 'c:\temp\smb1-computers.csv' -NoTypeInformation -UseCulture

Script to disable RDP

I'm trying to disable RDP using powershell.
I've tried the following code, but the values on the machine name I'm listing aren't changing.
$file = Get-Content c:\PSscripts\regchange\computers.txt
foreach ($computername in $file){
$PingStatus = Gwmi Win32_PingStatus -Filter "Address = '$computername'" | Select-Object StatusCode
If ($PingStatus.StatusCode -eq 0){
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $computername )
$regKey= $reg.OpenSubKey("System\\CurrentControlSet\\Control\\Terminal Server" ,$true)
$regKey.SetValue("fDenyTSConnections","1",[Microsoft.Win32.RegistryValueKind]::dword)
}
else {
Write-Host "$computername unreachable"
}
}
I suspect there's something wrong with the way I entered the registry path name. any help would be appreciated.
The issue must be either permissions (which I assume you have as there are no obvious error messages), refreshing issue or in Get-Content and the structure of your file.
In order for Get-Content to work in this manner, each computer on a separate line. e.g.:
MyComputer1
MyComputer2
Another troubleshooting step is to try adding in Write-Host $computername entries to verify that you are looping through properly.:
$file = Get-Content c:\PSscripts\regchange\computers.txt
foreach ($computername in $file){
$PingStatus = Gwmi Win32_PingStatus -Filter "Address = '$computername'" | Select-Object StatusCode
If ($PingStatus.StatusCode -eq 0){
Write-Host "$computername set"
}
else {
Write-Host "$computername unreachable"
}
}
You can also confirm by adding in a $regKey.GetValue after setting:
$file = Get-Content c:\PSscripts\regchange\computers.txt
foreach ($computername in $file){
$PingStatus = Gwmi Win32_PingStatus -Filter "Address = '$computername'" | Select-Object StatusCode
If ($PingStatus.StatusCode -eq 0){
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $computername )
$regKey= $reg.OpenSubKey("System\\CurrentControlSet\\Control\\Terminal Server" ,$true)
$regKey.SetValue("fDenyTSConnections","1",[Microsoft.Win32.RegistryValueKind]::dword)
Write-Host "$computername set to: $($regKey.GetValue("fDenyTSConnections"))"
}
else {
Write-Host "$computername unreachable"
}
}
Manually setting $computername = "MyComputer" and running the code, I can confirm that the code for setting the registry works... I can also confirm that remotely killing your RDP access to your remote virtual workstation also works.. and... is as terrible as it sounds ;-)
If PSRemoting is enabled, try something like this …
(This needs to be executed in a PowerShell elevated admin session.)
Get-Content -Path 'c:\PSscripts\regchange\computers.txt' |
ForEach{
If (Test-Connection -$PSItem -Count 1 -Quiet)
{
$paramblock = #{
Path = 'HKLM:\System\CurrentControlSet\Control\Terminal Server'
Name = 'fDenyTSConnections'
Value = '1'
}
Invoke-Command –Computername $PSItem –ScriptBlock {Set-ItemProperty #paramblock}
}
Else
{Write-Warning -Message "Either the host $PSItem is offline or not reachable."}
}

Powershell: Trying to locate file in multiple drives from list of servers

I'm trying (and failing) to:
Connect to the server by iterating through a list.
Confirm location where file exists (1 of 3 locations).
Replace a string in that file.
I've tried to do this multiple ways. There are two that I have which do part of what I want.
Can someone please help me understand if there's something I'm doing inefficiently or how to put all this together?
This one can loop through the servers and find the file
$ErrorActionPreference = 'SilentlyContinue'
$nope=$null
$servers= Get-Content C:\Servers.txt
foreach ($server in $servers)
{
If (Test-Connection -ComputerName $server -Quiet)
{Invoke-Command -ComputerName $server -ScriptBlock {$file=(Get-Childitem -Path C:\DiskSpace.ps1, D:\DiskSpace.ps1, Y:\DiskSpace.ps1); Write-Host "Found $file on $env:computername."}}
Else {
Write-Host ">> Could not connect to $server."; $nope += $server}
}
Write-Host $nope
...and this one can at least find a local file
$valid=#('')
$paths = #("C:\Users\user_name\Desktop\DiskSpace.ps1","C:\DiskSpace.ps1","D:\DiskSpace.ps1","Y:\DiskSpace.ps1")
Foreach ($path in $paths)
{
if (Test-Path $path)
{$valid += $path}
}
write-host $valid
Here's how I intend to to replace the string:
$ErrorActionPreference = 'SilentlyContinue'
$find=(Get-Childitem -Path C:\, D:\, Y:\ -include DiskSpace.ps1 -Recurse)
Write-Host $find
$ErrorActionPreference = 'Stop'
try {
(Get-Content $find).replace('bad_email#domain.com', 'good_email#domain.com') | Set-Content $find
}
catch {
}
Get-Content $find
You had all the pieces already. Simply loop over your Get-Content command for each file in the Invoke-Command.
$ErrorActionPreference = 'SilentlyContinue'
$servers = Get-Content C:\Servers.txt
$files = #('C:\DiskSpace.ps1', 'D:\DiskSpace.ps1', 'Y:\DiskSpace.ps1')
$report = foreach ($server in $servers) {
if (Test-Connection -ComputerName $server -Quiet) {
$response = Invoke-Command -ComputerName $server -ScriptBlock {
Get-Childitem -Path $using:files | ForEach-Object {
(Get-Content $_).replace('bad_email#domain.com', 'good_email#domain.com') | Set-Content $_
[PSCustomObject]#{
Name = $env:COMPUTERNAME
Message = "$($_.fullname) updated."
}
}
}
if ($response -eq $null) {
[PSCustomObject]#{
Name = $env:COMPUTERNAME
Message = "No files found"
}
} else {
$response
}
} else {
[PSCustomObject]#{
Name = $env:COMPUTERNAME
Message = "Unreachable"
}
}
}
$report

get last user logon time without AD

I'm trying to create a script that can get the user profiles that haven't logged on a specific computer within 30 days NOT using active directory but my script didn't work. I am using Powershell version 3. This is my code:
netsh advfirewall firewall set rule group="Windows Management Instrumentation (WMI)" new enable=yes
$ComputerList = Get-Content C:\temp\Computers1.txt
$myDomain = Get-Content C:\temp\Domain.txt
$csvFile = 'C:\temp\Profiles.csv'
# Create new .csv output file
New-Item $csvFile -type file -force
# Output the field header-line to the CSV file
"HOST,PROFILE" | Add-Content $csvFile
# Loop over the list of computers from the input file
foreach ($Computer in $ComputerList) {
# see if ping test succeeds for this computer
if (Test-Connection $Computer -Count 3 -ErrorAction SilentlyContinue) {
$ComputerFQDN = $Computer + $myDomain
$Profiles = Get-WmiObject -Class Win32_UserProfile -Computer $ComputerFQDN | Where{$_.LocalPath -notlike "*$env:SystemRoot*"}
foreach ($profile in $profiles) {
try {
$objSID = New-Object System.Security.Principal.SecurityIdentifier($profile.LocalPath) | Where {((Get-Date)-$_.lastwritetime).days -ge 30}
#| Where-Object {$_.LastLogonDate -le $CurrentDate.AddDays(-60)}
$objuser = $objsid.Translate([System.Security.Principal.NTAccount])
$objusername = $objuser.value
} catch {
$objusername = $profile.LocalPath
}
switch($profile.status){
1 { $profileType="Temporary" }
2 { $profileType="Roaming" }
4 { $profileType="Mandatory" }
8 { $profileType="Corrupted" }
default { $profileType = "LOCAL" }
}
$User = $objUser.Value
#output profile detail for this host
"$($Computer.toUpper()), $($objusername)" | Add-Content $csvFile
}
} else {
#output failure message for this host
"$($Computer.toUpper()), PING TEST FAILED" | Add-Content $csvFile
}
#LOOP
}
I tried to change the -ge to -le in the line $objSID = New-Object System.Security.Principal.SecurityIdentifier($profile.LocalPath) | Where {((Get-Date)-$_.lastwritetime).days -ge 30}, as well as changing the range after it but it still gave me the same list of computers regardless of my changes.
There are a few problems with the script, most notable is that your use of Where-Object is testing an object (SID) that doesn't know anything about dates.
I would break it down a little differently. I would write a function to catch all the stuff I need to do to attempt to figure out the last logon. That's my goes in my stack of utility functions in case I need it again.
Then I have something to use that function which deals with implementing the logic for the immediate requirement.
So you end up with this. It's a bit long, see what you think.
function Get-LastLogon {
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline = $true)]
[String]$ComputerName = $env:COMPUTERNAME
)
process {
Get-WmiObject Win32_UserProfile -ComputerName $ComputerName -Filter "Special='FALSE'" | ForEach-Object {
# Attempt to get the UserAccount using WMI
$userAccount = Get-WmiObject Win32_UserAccount -Filter "SID='$($_.SID)'" -ComputerName $ComputerName
# To satisfy WMI all single \ in a path must be escaped.
# Prefer to use NTUser.dat for last modification
$path = (Join-Path $_.LocalPath 'ntuser.dat') -replace '\\', '\\'
$cimObject = Get-WmiObject CIM_DataFile -Filter "Name='$path'" -ComputerName $ComputerName
if ($null -eq $cimObject) {
# Fall back to the directory
$path = $_.LocalPath -replace '\\', '\\'
$cimObject = Get-WmiObject CIM_Directory -Filter "Name='$path'" -ComputerName $ComputerName
}
$lastModified = $null
if ($null -ne $cimObject) {
$lastModified = [System.Management.ManagementDateTimeConverter]::ToDateTime($cimObject.LastModified)
}
# See if LastUseTime is more useful.
$lastUsed = $null
if ($null -ne $_.LastUseTime) {
$lastUsed = [System.Management.ManagementDateTimeConverter]::ToDateTime($_.LastUseTime)
}
# Profile type
$profileType = switch ($_.Status) {
1 { "Temporary" }
2 { "Roaming" }
4 { "Mandatory" }
8 { "Corrupted" }
0 { "LOCAL" }
}
[PSCustomObject]#{
ComputerName = $ComputerName
Username = $userAccount.Caption
LastChanged = $lastModified
LastUsed = $lastUsed
SID = $_.SID
Path = $_.LocalPath
ProfileType = $profileType
}
}
}
}
$myDomain = Get-Content C:\temp\Domain.txt
Get-Content C:\temp\Computers1.txt | ForEach-Object {
$ComputerName = $_ + $myDomain
if (Test-Connection $ComputerName -Quiet -Count 3) {
Get-LastLogon -ComputerName $ComputerName | Select-Object *, #{Name='Status';Expression={ 'OK' }} |
Where-Object { $_.LastChanged -lt (Get-Date).AddDays(-30) }
} else {
# Normalise the output so we don't lose columns in the export
$ComputerName | Select-Object #{Name='ComputerName';e={ $ComputerName }},
Username, LastChanged, LastUsed, SID, Path, ProfileType, #{Name='Status';Expression={ 'PING FAILED' }}
}
} | Export-Csv 'C:\temp\Profiles.csv' -NoTypeInformation