Wednesday, March 19, 2014

Computer Hardware Inventory

# On error the script will continue silently without
$erroractionpreference = "SilentlyContinue"
# TXT file containing the computers your pinging

$testcomputers = gc -Path "path to the text file where computers list is located"


$test_computer_count = $testcomputers.Length;

$x = 0;

write-host -foregroundcolor cyan ""

write-host -foregroundcolor cyan "Testing $test_computer_count computers, this may take a while."

foreach ($computer in $testcomputers) {

        # I only send 2 echo requests to speed things up, if you want the defaut 4

        # delete the -count 2 portion

   if (Test-Connection -ComputerName $computer -Quiet -count 2){

 

        Add-Content -value $computer -path The path to the livePCs.txt file
# example d:\output\livePCs.txt

        }else{



        Add-Content -value $computer -path The path to the deadPCs.txt file
# example d:\output\deadPCs.txt

        }

    $testcomputer_progress = [int][Math]::Ceiling((($x / $test_computer_count) * 100))

    # Progress bar

    Write-Progress  "Testing Connections" -PercentComplete $testcomputer_progress -Status "Percent Complete - $testcomputer_progress%" -Id 1;

    Sleep(1);

    $x++;



}

write-host -ForegroundColor cyan ""

write-host -foregroundcolor cyan "Testing Connection complete"

write-host -foregroundcolor cyan ""



$ComputerName = gc -Path "d:\output\livePCs.txt"



$computer_count = $ComputerName.Length;

# The results of the script are here Change as per your need

$exportLocation = "d:\output\pcInventory-$((Get-Date -uformat %Y%m%d).ToString()).csv"

$i = 0;

 foreach ($Computer in $ComputerName){

   $Bios =get-wmiobject win32_bios -Computername $Computer

   $Hardware = get-wmiobject Win32_computerSystem -Computername $Computer

   $Sysbuild = get-wmiobject Win32_WmiSetting -Computername $Computer

   $OS = gwmi Win32_OperatingSystem -Computername $Computer

   $Networks = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $Computer | ? {$_.IPEnabled}

   $driveSpace = gwmi win32_volume -computername $Computer -Filter 'drivetype = 3' |

   select PScomputerName, driveletter, label, @{LABEL='GBfreespace';EXPRESSION={"{0:N2}" -f($_.freespace/1GB)} } |

   Where-Object { $_.driveletter -match "C:" }
 
   $cpu = Get-WmiObject Win32_Processor  -computername $computer

   $username = Get-ChildItem "\\$computer\c$\Users\" | Sort-Object LastWriteTime -Descending | Select Name, LastWriteTime -first 1

   $totalMemory = [math]::round($Hardware.TotalPhysicalMemory/1024/1024/1024, 2)

   $lastBoot = $OS.ConvertToDateTime($OS.LastBootUpTime)



   #write-host -foregroundcolor yellow "Found $computer"

   $computer_progress = [int][Math]::Ceiling((($i / $computer_count) * 100))

    # Progress bar

    Write-Progress  "Gathering Hardware Info" -PercentComplete $computer_progress -Status "Percent Complete - $computer_progress%" -Id 1;

    Sleep(1);

    $i++;

   foreach ($Network in $Networks) {

    $IPAddress  = $Network.IpAddress[0]

    $MACAddress  = $Network.MACAddress

    $systemBios = $Bios.serialnumber

    $OutputObj  = New-Object -Type PSObject

    $OutputObj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Computer.ToUpper()

    $OutputObj | Add-Member -MemberType NoteProperty -Name Manufacturer -Value $Hardware.Manufacturer

    $OutputObj | Add-Member -MemberType NoteProperty -Name Model -Value $Hardware.Model

    $OutputObj | Add-Member -MemberType NoteProperty -Name CPU_Info -Value $cpu.Name

    $OutputObj | Add-Member -MemberType NoteProperty -Name SystemType -Value $Hardware.SystemType

    $OutputObj | Add-Member -MemberType NoteProperty -Name BuildVersion -Value $SysBuild.BuildVersion

    $OutputObj | Add-Member -MemberType NoteProperty -Name OS -Value $OS.Caption

    $OutputObj | Add-Member -MemberType NoteProperty -Name SPVersion -Value $OS.csdversion

    $OutputObj | Add-Member -MemberType NoteProperty -Name SerialNumber -Value $systemBios

    $OutputObj | Add-Member -MemberType NoteProperty -Name IPAddress -Value $IPAddress

    $OutputObj | Add-Member -MemberType NoteProperty -Name MACAddress -Value $MACAddress

    $OutputObj | Add-Member -MemberType NoteProperty -Name UserName -Value $username.Name

    $OutputObj | Add-Member -MemberType NoteProperty -Name Last-Login -Value $username.LastWriteTime

    $OutputObj | Add-Member -MemberType NoteProperty -Name C:_GBfreeSpace -Value $driveSpace.GBfreespace

    $OutputObj | Add-Member -MemberType NoteProperty -Name Total_Physical_Memory -Value $totalMemory

    $OutputObj | Add-Member -MemberType NoteProperty -Name Last_Reboot -Value $lastboot

    $OutputObj | Export-Csv $exportLocation -Append

   }

}



 write-host -foregroundcolor cyan "Script is complete, the results are here: $exportLocation"

Using Robocopy in Powershell

## The Below Script copies/mirrors  a Entire directory tree from source to destination with the Windows builtin roboust command robocopy.
## Exit codes from robocopy are logged to Windows Eventlog.

## Usage: Run with administrative rights in Windows Task Scheduler or Administrator:PowerShell
## If not executed with administrative privileges the script will not write to eventlog.

## Change these parameters
## ================================================================

## Name of the job, name of source in Windows Event Log and name of robocopy Logfile.
$JOB = "CopyJob"

## Source directory
$SOURCE = "Source goes here"

## Destination directory. Files in this directory will mirror the source directory. Extra files will be deleted!
$DESTINATION = "Destination"

## Path to robocopy logfile
$LOGFILE = "Location where is the log file needs to be stored"

## Log events from the script to this location
$SCRIPTLOG = "Location where is the Event  Logs files needs to be stored"

## Mirror a direcotory tree
$WHAT = @("/MIR")
## /COPY:DATS: Copy Data, Attributes, Timestamps, Security
## /SECFIX : FIX file SECurity on all files, even skipped files.

## Retry open files 3 times wait 30 seconds between tries.
$OPTIONS = @("/R:3","/W:30","/NDL","/NFL")
## /NFL : No File List - don't log file names.
## /NDL : No Directory List - don't log directory names.
## /L   : List only - don't copy, timestamp or delete any files.

## This will create a timestamp like yyyy-mm-yy
$TIMESTAMP = get-date -uformat "%Y-%m%-%d"

## This will get the time like HH:MM:SS
$TIME = get-date -uformat "%T"

## Append to robocopy logfile with timestamp
$ROBOCOPYLOG = "/LOG+:$LOGFILE`-Robocopy`-$TIMESTAMP.log"

## Wrap all above arguments
$cmdArgs = @("$SOURCE","$DESTINATION",$WHAT,$ROBOCOPYLOG,$OPTIONS)

## ================================================================

## Start the robocopy with above parameters and log errors in Windows Eventlog.
& C:\Windows\System32\Robocopy.exe @cmdArgs

## Get LastExitCode and store in variable
$ExitCode = $LastExitCode

$MSGType=@{
"16"="Errror"
"8"="Error"
"4"="Warning"
"2"="Information"
"1"="Information"
"0"="Information"
}

## Message descriptions for each ExitCode.
$MSG=@{
"16"="Serious error. robocopy did not copy any files.`n
Examine the output log: $LOGFILE`-Robocopy`-$TIMESTAMP.log"
"8"="Some files or directories could not be copied (copy errors occurred and the retry limit was exceeded).`n
Check these errors further: $LOGFILE`-Robocopy`-$TIMESTAMP.log"
"4"="Some Mismatched files or directories were detected.`n
Examine the output log: $LOGFILE`-Robocopy`-$TIMESTAMP.log.`
Housekeeping is probably necessary."
"2"="Some Extra files or directories were detected and removed in $DESTINATION.`n
Check the output log for details: $LOGFILE`-Robocopy`-$TIMESTAMP.log"
"1"="New files from $SOURCE copied to $DESTINATION.`n
Check the output log for details: $LOGFILE`-Robocopy`-$TIMESTAMP.log"
"0"="$SOURCE and $DESTINATION in sync. No files copied.`n
Check the output log for details: $LOGFILE`-Robocopy`-$TIMESTAMP.log"
}

## Function to see if running with administrator privileges
function Test-Administrator
{
    $user = [Security.Principal.WindowsIdentity]::GetCurrent();
    (New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
}

## If running with administrator privileges
If (Test-Administrator -eq $True) {
"Has administrator privileges"

## Create EventLog Source if not already exists
if ([System.Diagnostics.EventLog]::SourceExists("$JOB") -eq $false) {
"Creating EventLog Source `"$JOB`""
    [System.Diagnostics.EventLog]::CreateEventSource("$JOB", "Application")
}

## Write known ExitCodes to EventLog
if ($MSG."$ExitCode" -gt $null) {
Write-EventLog -LogName Application -Source $JOB -EventID $ExitCode -EntryType $MSGType."$ExitCode" -Message $MSG."$ExitCode"
}
## Write unknown ExitCodes to EventLog
else {
Write-EventLog -LogName Application -Source $JOB -EventID $ExitCode -EntryType Warning -Message "Unknown ExitCode. EventID equals ExitCode"
}
}
## If not running with administrator privileges
else {
## Write to screen and logfile
Add-content $SCRIPTLOG "$TIMESTAMP $TIME No administrator privileges" -PassThru
Add-content $SCRIPTLOG "$TIMESTAMP $TIME Cannot write to EventLog" -PassThru

## Write known ExitCodes to screen and logfile
if ($MSG."$ExitCode" -gt $null) {
Add-content $SCRIPTLOG "$TIMESTAMP $TIME Printing message to logfile:" -PassThru
Add-content $SCRIPTLOG ($TIMESTAMP + ' ' + $TIME + ' ' + $MSG."$ExitCode") -PassThru
Add-content $SCRIPTLOG "$TIMESTAMP $TIME ExitCode`=$ExitCode" -PassThru
}
## Write unknown ExitCodes to screen and logfile
else {
Add-content $SCRIPTLOG "$TIMESTAMP $TIME ExitCode`=$ExitCode (UNKNOWN)" -PassThru
}
Add-content $SCRIPTLOG ""
Return
}