Category Archives: PowerShell

Get LastReboot and Uptime value on Windows 10 and Windows Server via PS

In this lab, I have used PS to get LastReboot and Uptime value on Windows servers and clients. PS script will query “Get-WmiObject” to get the last boot time of the computers/servers.

Firstly, I will test with Windows Servers.

$OS1 = Get-WmiObject Win32_OperatingSystem -ComputerName DC1 -ErrorAction Stop
$LastReboot =($OS1.ConvertToDateTime($OS1.LastBootUpTime))
# Print LastReboot
$LastReboot
$Uptime = (Get-Date) -$OS1.ConvertToDateTime($OS1.LastBootUpTime)
$Uptime  = ([String]$Uptime.Days + " Days " + $Uptime.Hours + " Hours " + $Uptime.Minutes + " Minutes")
# Print uptime

Write a full PS script.

# This script is written by Tung on 2022-02-18
# This is used to get lastreboot and uptime on Windows servers.
# Get time when running the script
$filename = (Get-Date).tostring("dd-MM-yyyy-hh-mm")
# Change PowerShell working directory to C:\Shared
Set-Location C:\Shared
#$TestComputerName = get-content C:\Shared\tungmachine.txt
$servers = (Get-ADComputer -properties OperatingSystem -filter{(operatingsystem -like "*Windows Server*")}).name
Foreach ($server in $servers) {
        # Only check the machine if it is online
        $ping_result = Test-Connection -ComputerName $server -Count 1 -Quiet
        # If the machine is online
        if($ping_result){
        # Using "Get-WmiObject Win32_OperatingSystem" to get $OS object
        # Using "Get-WmiObject Win32_OperatingSystem -ComputerName $Testcomputer -ErrorAction Stop" to get $OS object on remote machines.
        $OS = Get-WmiObject Win32_OperatingSystem -ComputerName $server -ErrorAction Stop
        # Get LastReboot via $OS.LastBootUpTime variable
        $LastReboot =($OS.ConvertToDateTime($OS.LastBootUpTime)).tostring("dd-MM-yyyy")    
        # Get Uptime via $OS.LastBootUpTime variable
        $Uptime = (Get-Date) -$OS.ConvertToDateTime($OS.LastBootUpTime)
        # Create a hash table (dictionary type) with 3 columns: PSComputerName, LastReboot and Uptime
        $lastlogonproperties = @{
        # Add PSComputerName into column #1
        PSComputerName  = $server
        # Convert and only get dd-mm-yyyy on last reboot variable.
        # Add LastReboot into column #2
        # Only get dd-mm-yyy field on LastReboot record.
        LastReboot =($OS.ConvertToDateTime($OS.LastBootUpTime)).tostring("dd-MM-yyyy")
        # Add LastReboot into column #3
        Uptime  = ([String]$Uptime.Days + " Days " + $Uptime.Hours + " Hours " + $Uptime.Minutes + " Minutes")
        }

    # Create a new table object on PS to append the hash table values above   
    $forcecsv = New-Object psobject -Property $lastlogonproperties
    # change order of columns before appending to csv file. 
    # Convert it to csv file and save under LastReboot directory.
    $forcecsv | select-object PSComputerName, LastReboot, Uptime | export-csv -NoTypeInformation -append "C:\Shared\LastReboot\Server\$filename.csv"
    }
}

Run the script.

Then, do the same PS script to query Windows 10 machines.

Change “(operatingsystem -like “*Windows Server*”)” to (operatingsystem -like “*Windows 10*”)

$computers = (Get-ADComputer -properties OperatingSystem -filter{(operatingsystem -like "*Windows 10*")}).name
# This script is written by Tung on 2022-02-18
# This is is used t get lastreboot and uptime on Windows 10 machines.
# Get time when running the script
$filename = (Get-Date).tostring("dd-MM-yyyy-hh-mm")
# Change PowerShell working directory to C:\Shared
Set-Location C:\Shared
#$TestComputerName = get-content C:\Shared\tungmachine.txt
$computers = (Get-ADComputer -properties OperatingSystem -filter{(operatingsystem -like "*Windows 10*")}).name
Foreach ($Computer in $computers) {
        # Only check the machine if it is online
        $ping_result = Test-Connection -ComputerName $Computer -Count 1 -Quiet
        # If the machine is online
        if($ping_result){
        # Using "Get-WmiObject Win32_OperatingSystem" to get $OS object
        # Using "Get-WmiObject Win32_OperatingSystem -ComputerName $Testcomputer -ErrorAction Stop" to get $OS object on remote machines.
        $OS = Get-WmiObject Win32_OperatingSystem -ComputerName $Computer -ErrorAction Stop
        # Get LastReboot via $OS.LastBootUpTime variable
        $LastReboot =($OS.ConvertToDateTime($OS.LastBootUpTime)).tostring("dd-MM-yyyy")    
        # Get Uptime via $OS.LastBootUpTime variable
        $Uptime = (Get-Date) -$OS.ConvertToDateTime($OS.LastBootUpTime)
        # Create a hash table (dictionary type) with 3 columns: PSComputerName, LastReboot and Uptime
        $lastlogonproperties = @{
        # Add PSComputerName into column #1
        PSComputerName  = $Computer
        # Convert and only get dd-mm-yyyy on last reboot variable.
        # Add LastReboot into column #2
        # Only get dd-mm-yyy field on LastReboot record.
        LastReboot =($OS.ConvertToDateTime($OS.LastBootUpTime)).tostring("dd-MM-yyyy")
        # Add LastReboot into column #3
        Uptime  = ([String]$Uptime.Days + " Days " + $Uptime.Hours + " Hours " + $Uptime.Minutes + " Minutes")
        }

    # Create a new table object on PS to append the hash table values above   
    $forcecsv = New-Object psobject -Property $lastlogonproperties
    # change order of columns before appending to csv file. 
    # Convert it to csv file and save under LastReboot directory.
    $forcecsv | select-object PSComputerName, LastReboot, Uptime | export-csv -NoTypeInformation -append "C:\Shared\LastReboot\Client\$filename.csv"
    }
}

Run the script.

PowerShell commands and notes

PowerShell commands and notes:

#Recursive file search using PowerShell
Get-ChildItem -Path C:\ -Filter *Graylog* -Recurse -ErrorAction SilentlyContinue -Force
#checkdate in the last 24 hours
$checkdate = (Get-Date).AddHours(-24)
#check all files have been modified in the last 24 hours and output file name, size and the time was last modified
Get-ChildItem -Path C:\Shared -file -Recurse | Where-Object {$_.LastWriteTime -ge $checkdate} | Select-Object -Property Fullname,Length,LastWriteTime
#checkdate in the last 90days
$checkdate = (Get-Date).AddDays(-90)
#check files on the  C:\users\Administrator\Downloads directory and at least 100MB in size and LastWriteTime is less than $checkdate. Then output the result to csv file.
$files = Get-ChildItem -Path C:\users\Administrator\Downloads -file -Recurse |
Where-Object {$_.length -ge 100MB -AND $_.LastWriteTime -le $checkdate} |
Select Fullname,Length,CreationTime,LastWriteTime |
Export-CSV -Path myfiles-90days_100MB.csv

Check WinRM service is running on a remote host.

Test-NetConnection -ComputerName WIN10NEW11 -Port 5985 -WarningAction SilentlyContinue
#shows the last computer name started, running.
get-CimInstance -ClassName win32_operatingsystem -ComputerName $env:computername | Select-Object -property PSComputerName, LastBootUpTime, {(Get-Date) - $_.lastbootuptime}

Get Antivirus Product is installed and its status with PowerShell.

Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntivirusProduct

List the user accounts in the local administrator group in a Windows machine.

Get-CimInstance win32_group -filter "name = 'administrators' AND LocalAccount = 'true'" | Get-CimAssociatedInstance -ResultClassName win32_useraccount

List all installed software that has a name defined in a Windows machine.

Get-CimInstance win32_product -filter "name like '%'" | Select-Object -property Name,Vendor,Version,Description,InstallDate

Check if Wordpad is running, kills the Wordpad process, and then creates a sample text file that includes the current date that kills the process.

(Get-Process wordpad -ea silentlycontinue) -and (stop-process -name wordpad) -and ("$(Get-Date) killed wordpad") | Out-file C:\Shared\wordpadlog.txt

Search any files that have file extension is .srt on D:\Shared folder, then remove them.

Check before removing.
PS D:\Get-Childitem -path "D:\Shared" -Filter *.srt -Recurse -ErrorAction SilentlyContinue -Force | Remove-Item -Force -Whatif


PS D:\Get-Childitem -path "D:\Shared" -Filter *.srt -Recurse -ErrorAction SilentlyContinue -Force | Remove-Item -Force

Install IIS Web server via PS.

Add-WindowsFeature Web-Server, Web-WebServer, Web-Common-Http, Web-Default-Doc, Web-Dir-Browsing, Web-Http-Errors, Web-Static-Content, Web-Health, Web-Http-Logging, Web-Log-Libraries, Web-Request-Monitor, Web-Performance, Web-Stat-Compression, Web-Security, Web-Filtering, Web-Windows-Auth, Web-App-Dev, Web-Net-Ext45, Web-Asp-Net45, Web-ISAPI-Ext, Web-ISAPI-Filter, Web-Mgmt-Tools, Web-Mgmt-Console, Web-Mgmt-Compat, Web-Metabase, NET-Framework-45-Features, NET-Framework-45-Core, NET-Framework-45-ASPNET, NET-WCF-Services45, NET-WCF-HTTP-Activation45, NET-WCF-TCP-PortSharing45, WAS, WAS-Process-Model, WAS-Config-APIs -restart

Install Active Directory module via PS.

Import-Module ServerManager
Add-WindowsFeature -Name "RSAT-AD-PowerShell" –IncludeAllSubFeature

# Check the installation status of a module
Get-WindowsFeature RSAT-AD-PowerShell

Shut down and Restart Windows machine.

# Stop-Computer -Force -WhatIf
Stop-Computer -Force
# Restart-Computer -Force -WhatIf
Restart-Computer -Force
# Delay restart on 5 seconds
Start-Sleep -Seconds 5 ; Restart-Computer -Force
# Restart machine remotely
Restart-Computer -ComputerName PC1 -Force
# Restart-Computer (Multiple Windows 10 domain joined clients)

(Get-ADComputer -Filter 'operatingsystem -notlike "*server*"').Name | Restart-Computer -Force -ErrorAction silentlycontinue

Get, stop and start Windows services.

Get-Service
# search Windows updates service.
Get-Service | where-object {$_.name -like "*wuauserv*"}
# Start Windows updates service.
Start-Service wuauserv -PassThru
# Stop Windows updates service.
Stop-Service wuauserv -PassThru
# Get Windows updates status
Get-Service -name wuauserv
# Change statustype 
Set-Service -name wuauserv -StartupType Disabled -Status Stopped

Force installing Windows updates via PowerShell PSWindowUpdates

F_PSWindowsUpdates.PS1 is shared on \\DC1\Shared

# This is PowerShell script to force on installing Windows Updates via PSWindowsUpdate on Windows machines
# https://www.powershellgallery.com/packages/PSWindowsUpdate/2.2.0.2
# It is created on 2021-10-21
# Allow PowerShell to be run on Windows machines with PSWindowsUpdate module
Set-ExecutionPolicy RemoteSigned
# Installs everything (newest version) along with required modules.
Install-Module PSWindowsUpdate
# Import Module PSWindowsUpdate before running the script
Import-Module -Name PSWindowsUpdate
# Force Windows updates are completely downloaded, installed and then restarted. Will check if we have a WSUS server
Install-WindowsUpdate -AcceptAll -AutoReboot
# Send an email after running PSWindowsUpdate command
# Will send email if the last previous command is successful.
if ($? -eq $True){
        # Use this command for TLS requirement
        [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
        # Get machine name
        $machinename = get-content env:computername
        # Get current date and time
        $currentdate = get-date
        # Get current date and time
        $currentdate = get-date
        # SMTP server of Xyz.com</p>
        $SMTP = "smtp-mail.xyz.com"
        # Mail from<
        $From = "youremail@xyz.com"
        # Rcpt to
        $To = "youremail@xyz.com"# Subject line
        $Subject = "Windows updates on $cname"
        # Email body
        $Body = "Finising running Windows updates on $machinename on $currentdate"
        #Create a connection to SMTP Outlook via the port 587</p>
        $Email = New-Object Net.Mail.SmtpClient($SMTP, 587)
        # Enable SSL for the connection
        Email.EnableSsl = $true
        #Log in to xyz mail server with your credential
        $Email.Credentials = New-Object System.Net.NetworkCredential("youremail@xyz.com", "yourpassword");
        # Send email syntax
        $Email.Send($From, $To, $Subject, $Body)
}

Assign this script on Task Scheduler.