Following is reference post for Powershell command line usage to achieve different tasks. Recently I had to perform various administration tasks on more than 20 windows based servers , and using scripting it made my life a bit easier and I let the scripting do the task on my behalf on scheduled basis 😉
These are very common tasks, commands but when you combine them with the Linux shell, they become ultra powerful and best thing is that you can create / add some ‘ Artificial Intelligence ‘ in it. I have posted just basic level to hide the sensitivity of original tasks.
Following is collection of my own R&D, some commands are picked from Stackoverflow/Spicework forums as well.
General PowerShell Related CMD
DHCP Related PS commands. I use it to quick search IP / MAC etc. Also it can be used to add reservation using PS cmds. You can also bind them with scripting as well to make your life easy.
# Get all leases from DHCP Server Get-DhcpServerv4Lease -ComputerName 10.0.0.1 -ScopeId 101.0.0.0 Get-DhcpServerv4Lease -ComputerName 10.0.0.1 -ScopeId 101.0.0.0 -AllLeases # Get particular information only Get-DhcpServerv4Lease -ComputerName 10.0.0.1 -ScopeId 101.0.0.0 | select-object IPAddress,ClientId,HostName,Description # Search user by MAC Address Get-DhcpServerv4Lease -ComputerName 10.0.0.1 -ScopeId 101.0.0.0 -EA SilentlyContinue -ClientId b0-6f-e0-ad-e2-8b # Search user by mac IP ADdress Get-DhcpServerv4Lease -ComputerName 10.0.0.1 -IPAddress 10.0.17.200 # Add Reservation for single IP using his MAC address Add-DhcpServerv4Reservation -ComputerName 10.0.0.1 -ScopeId 101.0.0.0 -IPAddress 10.0.14.59 -ClientId b0-6f-e0-ad-e2-8b -Description "MY PC 1" -Name "MY PC 1" # Add Gateway router for specific IP Set-DhcpServerv4OptionValue -ComputerName 10.0.0.1 -ReservedIP 10.0.14.59 -Router 10.0.0.100 Script to send email users list who have not logged in last 30 days using BLAT email too @echo off cls set srvname=DC01 set description=Domain Controller DC01 Weekly Report - Users list who have not logged in last 30 days set jobname=Domain Controller DC01 Weekly Report - Users list who have not logged in last 30 days set attachment=c:\backup\usersnotloggedlist.log set tmpfile=c:\backup\usersnotloggedlist_temp.log set mail-subject=Domain Controller DC01 Weekly Report - Users list who have not logged in last 30 days set mail-body=Domain Controller DC01 Weekly Report - Users list who have not logged in last 30 days set mail-to=syed.jahanzaib@XXX.com.pk set footer=Domain Controller DC01 Weekly Report - Users list who have not logged in last 30 days - Powered by XXX IS Dept. echo Domain Controller DC01 Weekly Report - Users list who have not logged in last 30 days > %attachment% echo. >> %attachment% powershell.exe -inputformat none -command "$DaysInactive = 30; $time = (Get-Date).Adddays(-($DaysInactive)); Get-ADUser -Filter {LastLogonTimeStamp -lt $time -and enabled -eq $true} -Properties * | select Name,UserPrincipalName,Enabled,LockedOut,Created,LastLogonDate,Description" > %tmpfile% echo Total Count: >> %attachment% find /C "UserPrincipalName" > %attachment% echo. >> %attachment% powershell.exe -inputformat none -command "$DaysInactive = 30; $time = (Get-Date).Adddays(-($DaysInactive)); Get-ADUser -Filter {LastLogonTimeStamp -lt $time -and enabled -eq $true} -Properties * | select Name,UserPrincipalName,Enabled,LockedOut,Created,LastLogonDate,Description" >> %attachment% echo Powershell Script Powered by XXX IS Dept. >> %attachment% rem ########## rem Email LOGS rem ########## c:\blat\blat.exe %attachment% -to %mail-to% -i %srvname% -s "%mail-subject%" rem ## THE END rem ## Syed Jahanzaib / XXX (Pvt) Ltd. / IS Dept.
Output:
<img class=” size-full wp-image-11450 aligncenter” src=”https://aacable.files.wordpress.com/2017/02/users-not-logged-in-email-report.png” alt=”users not logged in email report” width=”808″ height=”721″ /></pre>
<hr />
<h2>Clear Event Logs via PS command (runs as admin)</h2>
<pre>wevtutil el | foreach { wevtutil cl $_ }</pre>
<hr />
<h2><strong>Check PowerShell Version</strong></h2>
<pre>
$PSVersionTable.PSVersion
Upgrade PowerShell to Version 4 in Windows 7/2008 - 64bit
https://blogs.technet.microsoft.com/heyscriptingguy/2014/11/09/weekend-scripter-install-powershell-4-0-in-windows-7/
Execute Powershell script from Linux Shell using winexe
winexe -U DOMAIN/ID%’PASSWORD’ //IP_OR_NAME //101.11.12.38 ‘powershell.exe -inputformat none -command “dir”‘
winexe -U DOMAIN/ID%’PASSWORD’ //IP_OR_NAME ‘powershell.exe -inputformat none -command “c:\scripts\script_name.ps1″‘
Check Powershell Version & Process Architecture
#Check PowerShell Version $PSVersionTable # Check Processor Architecture $env:PROCESSOR_ARCHITECTURE
# Get list of installed HOTFIX with details Get-HotFix | Format-Table
# Import Active Directory module
import-module activedirectory
Show folders that have not been updated/modified by X Period of Time
In my company I have Windows 2008 R2 [as a file sharing / backup server] with a centralized shared folder structure like this
- D:\USERS
- D:\USERS\USER1
D:\USERS\USER1\AUTOBACKUP
D:\USERS\USER1\DROP
D:\USERS\USER1\EXHIBIT - D:\USERS\USER2
D:\USERS\USER2\AUTOBACKUP
D:\USERS\USER2\DROP
D:\USERS\USER2\EXHIBIT
There are are around 100+ users folders and all users copy their important data on a daily basis there corresponding AUTOBACKUP folder. Every AUTOBACKUP folder have several sub folders and files in it.
My requirements was to somehow display ONLY the AUTOBACKUP folders name which are not updated in last 1 month, means no file in written in any autobackup or in its subfolders. (I dont requires drop/exhibit folders details as it can be updated by any1 , but autobackup can be updated only by the corresponding user)
Result Something like:
- D:\USERS\USER1\AUTOBACKUP – Updated
- D:\USERS\USER2\AUTOBACKUP – ALERT: Not updated since last month …
or show me result only for users whose auto backup have not updated from past month.
I tried to get result by powershell commands, but it shows me results if some one update the drop/exhibit too, and i want to exclude them in search criteria, the search should be done only in autobackup.
So here was the solution :)~
Get-WmiObject Win32_LogicalDisk -Filter "DriveType='3'" ` -ComputerName SERVER_NAME | ` Format-Table ` @{l="Server";e={$_.SystemName}}, ` @{l="Drive Letter";e={$_.DeviceID}}, ` @{l="Free Space on Disk (GB)";e={"{0:n2}" -f ($_.freespace/1gb)}}, ` @{l="Total Disk Space (GB)";e={"{0:n2}" -f ($_.size/1gb)}}, ` @{l="Percentage Used";e={ "{0:P2}" -f (1 - ([Int64]$_.FreeSpace / [Int64]$_.Size)) }} $PrettySizeColumn = @{name="Size";expression={ $size = $_.Size if ( $size -lt 1KB ) { $sizeOutput = "$("{0:N2}" -f $size) B" } ElseIf ( $size -lt 1MB ) { $sizeOutput = "$("{0:N2}" -f ($size / 1KB)) KB" } ElseIf ( $size -lt 1GB ) { $sizeOutput = "$("{0:N2}" -f ($size / 1MB)) MB" } ElseIf ( $size -lt 1TB ) { $sizeOutput = "$("{0:N2}" -f ($size / 1GB)) GB" } ElseIf ( $size -lt 1PB ) { $sizeOutput = "$("{0:N2}" -f ($size / 1TB)) TB" } ElseIf ( $size -ge 1PB ) { $sizeOutput = "$("{0:N2}" -f ($size / 1PB)) PB" } $sizeOutput }} # change the folder name here ... Get-ChildItem 'D:\USERS' -Directory | ForEach-Object { $RecentAutoBackupFiles = @( # change the folder name here too ... Get-ChildItem -Path "D:\USERS\$($_.Name)\autobackup" -File -Recurse | Where-Object { $_.LastWriteTime -ge [datetime]::Now.AddMonths(-1) } ) if (0 -eq $RecentAutoBackupFiles.Count) { "$($_.Name) " } }
Result of above Script (which was executed using Linux bash script as usual:) )
Show Folder Size (in GB) | Sort by Size | Select top 10
This was intense task for me, and I was not able to sort it on my own. so I have to take help from stackoverflow and spicework forums.
Scenario:
We have a Windows 2008 R2 base file server where users have there shared folders.
Example:
- D:\USERS
- D:\USERS\USER1
- D:\USERS\USER2
- D:\USERS\USER3
- D:\USERS\USER4
- D:\USERS\USER5
All users folders have several hundreds sub folders in it.
Task:
Execute functions from Linux base system , which should remote to file server by winexe, execute powershell script, which should perform functions like
- List all users folder name
- Last modified time
- Size conversion auto in kb/mb/gb ( order by size)
- Email the result [customized] using sendEmail / gmail.
First the powershell script name foldersize.ps1
which will actually perform the functions on file server. we will copy this script in c:\temp on remote file server.
foldersize.ps1
param ($Path = ".") $disk = ([wmi]"\\FILESERVER\root\cimv2:Win32_logicalDisk.DeviceID='D:'") "D: GB Total = {0:#.0} D: GB Used {2:#.0} D: GB Free {1:#.0} " -f ($disk.Size/1GB),($disk.FreeSpace/1GB),($disk.Size/1GB-$disk.FreeSpace/1GB) | write-output Get-WmiObject Win32_LogicalDisk -Filter "DriveType='3'" ` -ComputerName FILESERVER | ` Format-Table ` @{l="Server";e={$_.SystemName}}, ` @{l="Drive Letter";e={$_.DeviceID}}, ` @{l="Free Space on Disk (GB)";e={"{0:n2}" -f ($_.freespace/1gb)}}, ` @{l="Total Disk Space (GB)";e={"{0:n2}" -f ($_.size/1gb)}}, ` @{l="Percentage Used";e={ "{0:P2}" -f (1 - ([Int64]$_.FreeSpace / [Int64]$_.Size)) }} $PrettySizeColumn = @{name="Size";expression={ $size = $_.Size if ( $size -lt 1KB ) { $sizeOutput = "$("{0:N2}" -f $size) B" } ElseIf ( $size -lt 1MB ) { $sizeOutput = "$("{0:N2}" -f ($size / 1KB)) KB" } ElseIf ( $size -lt 1GB ) { $sizeOutput = "$("{0:N2}" -f ($size / 1MB)) MB" } ElseIf ( $size -lt 1TB ) { $sizeOutput = "$("{0:N2}" -f ($size / 1GB)) GB" } ElseIf ( $size -lt 1PB ) { $sizeOutput = "$("{0:N2}" -f ($size / 1TB)) TB" } ElseIf ( $size -ge 1PB ) { $sizeOutput = "$("{0:N2}" -f ($size / 1PB)) PB" } $sizeOutput }} Get-ChildItem -Path $Path | Where-Object {$_.PSIsContainer} | ForEach-Object { $size = ( Get-ChildItem -Path $_.FullName -Recurse -Force | where {!$_.PSIsContainer} | Measure-Object -Sum Length).Sum $obj = new-object -TypeName psobject -Property @{ Path = $_.Name Time = $_.LastWriteTime Size = $size } $obj } | Sort-Object -Property Size -Descending | Select-Object Path, Time, $PrettySizeColumn
try to execute this file on the file server from powershell terminal. It should give you proper results. JUST BE VERY SURE TO READ THE SCRIPT VERY WELL, AS IT SHOULD BE MODIFIED AS PER YOUR REQUIREMENTS, PLUS I USED DOMAIN ADMIN ID, SO I HAD ALL THE ACCESS ON ALL THE COMPUTERS FROM MY PC /REMOTELY AS WELL.
.\foldersize.ps1 -Path \\FILESERVER\C$\Softwares\IMAGES_ISO
Once done, make a bash script in your linux (ubuntu) system which will execute the above script remotely and will customized the result and email to the admin.
BASH FILE / folder_iquiry.sh which will run the ps file from linux terminal
#!/bin/bash #set -x # This bash script will query remote file server storage using Powershell Commands. # It will send report via email with relevant details like top used folders , Very useful some times. # Syed Jahanzaib / aacableAThotmailDOTcom # http://aacableDOTwordpressDOTcom # 20-feb-2017 start=`date +%s` COMPANY="ZAIB" SRVNAME="SRV01" SRV_FRIENDLY_NAME="File Server D:Drive" IP="10.0.0.1" DOMAIN="DC.LOCAL" PASS="PASSWORD" ID="ADMIN" #TARGET DIRECTORY TDIR="d:\users" TEMP_HOLDER="/tmp/xdrive_temp_raw_report.txt" TEMP_HOLDER_FINAL="/tmp/xdrive_final_mail_report.txt" > $TEMP_HOLDER > $TEMP_HOLDER_FINAL DATE=`date` # GMAIL DETAILS to send EMAIL alert SENDMAILAPP="/temp/sendEmail-v1.56/sendEmail" GMAILID="ADMIN_GMAIL_ID@gmail.com" GMAILPASS="GMAIL_PASS" # Add recipient email address below ADMINMAIL1="aacableAThotmailDOTcom" MSG_SUB="$COMPANY $SRV_FRIENDLY_NAME - $SRVNAME - / Weekly Report @ $DATE" MSG_BODY="$COMPANY $SRV_FRIENDLY_NAME - $SRVNAME - Weekly Report for Users D: drive folder's sorted by size @ $DATE " FOOTER="Automated Weekly Report Generated using Linux Powered Powershell !! Sys. Admin $COMPANY IS Dept." echo " $MSG_BODY " > $TEMP_HOLDER #QUERY SERVER X: DRIVE winexe -U $DOMAIN/$ID%"$PASS" //$IP 'powershell.exe -inputformat none -command "c:\temp\foldersize.ps1 -Path '"$TDIR"' ' >> $TEMP_HOLDER # Remove Junk Line with unknown character, which is unique or specific occured in my lab test end=`date +%s` echo "It took $(($end - $start)) seconds to complete this task..." >> $TEMP_HOLDER echo " $FOOTER" >> $TEMP_HOLDER #Print result cat $TEMP_HOLDER #send email sendemail -u "$MSG_SUB" -o tls=yes -s smtp.gmail.com:587 -t $ADMINMAIL1 -xu $GMAILID -xp $GMAILPASS -f $GMAILID -o message-file=$TEMP_HOLDER -o message-content-type=text # Script ends here
Now execute file from linux terminal like this…
/temp/folder_inquiry.sh
SAMPLE:
Show Folder Size (in GB) | Sort by Size | Select top 10
[This method have one BIG disadvantage, dueto 260 characters limit in windows, it may not show files/folders above then this limit. so it may not give your correct result if you have some deep folder structure/long files name in it.]
#Windows PS Version ls c:\temp | select Name, @{Name="Type";Expression={if($_.psIsContainer){"---Directory---"}else{"---File---"}}}, @{Name="Size(GB)";Expression={[Math]::Round($(ls $_.FullName -recurse| measure Length -sum).Sum/1GB, 2)}}| sort -property "Size(GB)" -desc | Select -First 10 # Linux Winexe format winexe -U DC/ID%PASS //IP 'powershell.exe -inputformat none -command "ls c:\backup\ | select Name, @{Name='"'"'"Type"'"'"';Expression={if($_.psIsContainer){'"'"'"Directory"'"'"'}else{'"'"'"File"'"'"'}}}, @{Name='"'"'"Size(GB)"'"'"';Expression={[Math]::Round($(ls $_.FullName -recurse| measure Length -sum).Sum/1GB, 3)}}| sort -property '"'"'"Size(GB)"'"'"' -desc | Select -First 10"'
Example of C:\temp contents …
- C:\TEMP
- C:\TEMP\FOLDER1
- C:\TEMP\FOLDER-1\SUB_FOLDER
- C:\TEMP\FOLDER-1\SUB_FOLDER_MORE
- C:\TEMP\FOLDER2
- C:\TEMP\FOLDER3
This will query all folders/sub-folders inside the c:\temp folder, and display only the main folders name including sizes of subfolder as well ..
Name Type Size(GB) ---- ---- -------- Win2008_test Directory 28.9 Ubuntu-PHP-API Directory 2.75 ubuntu-freeradius Directory 2.15 zaib_temp_radius Directory 2.09 MIKROTIK-1 - Copy Directory 0.39
Show files with Name & Size greater than 5 GB
[This was required in a script where I schedule it to email the top users in mail server by querying the folder directly]
Following command is formatted to be executed by WINEXE [Linux]
winexe -U $DOMAIN/$ID%"$PASS" //$IP 'powershell.exe -inputformat none -command "Get-ChildItem -Path '"$TDIR"' | Where-Object {$_.length -gt 5GB} | Sort-Object -descending -Property Length | Format-Table Name,@{name='"'"'Size GB'"'"';expression={$_.length/1GB};FormatString='"'"'N1'"'"'}"' | sed -e "$DEL_LINE" | sed '/^\s*$/d' |nl >> $TEMP_HOLDER
Script to get specific folder files and specific folder total size, sort and email to admin on every Monday / Weekly
#!/bin/bash #set -x # This bash script will query remote lotus domino mail server storage using Powershell Commands. # It will send report via email with erelevant details, Very useful some times. # Syed Jahanzaib / aacableAThotmailDOTcom # http://aacableDOTwordpressDOTcom # 20-feb-2017 COMPANY="ZAIB" SRVNAME="MYSRV" IP="10.0.0.1" DOMAIN="DC_NAME" PASS="PASSWORD" ID="ADMINISTRATOR" TDIR="D:\lotus\domino\data\mail" TDIR_FULL="D:\lotus" TDIR_MAIL="D:\lotus\domino\data\mail" TDIR_ARCH="D:\lotus\domino\data\archive" # How many lines to be dleeted from winexe output for top users section DEL_LINE="1,3d" TEMP_HOLDER="/tmp/mail_top_users.txt" TEMP_HOLDER_FULL="/tmp/mail_lotus_folder_size.txt" > $TEMP_HOLDER DATE=`date` # GMAIL DETAILS to send EMAIL alert SENDMAILAPP="/temp/sendEmail-v1.56/sendEmail" GMAILID="ADMIN_GMAIL_ID@gmail.com" GMAILPASS="GMAIL_PASSWORD" # Add recipient email address below ADMINMAIL1="aacableAThotmailDOTcom" MSG_SUB="$COMPANY Lotus Mail Server / Weekly Report @ $DATE" MSG_BODY="$COMPANY - $SRVNAME - Lotus Mail Server Weekly Report for Total Usage and TOP users exceeding 5GB mailbox size @ $DATE " FOOTER="Automated Weekly Report Generated using Linux Powered Powershell !! Sys. Admin $COMPANY IS Dept." echo " $MSG_BODY " > $TEMP_HOLDER #Full size of Lotus Folder - Overall FULL_SIZE=`winexe -U $DOMAIN/$ID%"$PASS" //$IP 'powershell.exe -inputformat none -command " "\"{0:N0}"\" -f ( (Get-ChildItem -Path '"$TDIR_FULL"' -Recurse | Measure-Object -Property Length -Sum ).Sum / 1GB)"' |sed '/^\s*$/d'` echo "Lotus Total DATA size in GB = $FULL_SIZE" >> $TEMP_HOLDER #Full size of Lotus MAIL Folder only FULL_SIZE_MAIL=`winexe -U $DOMAIN/$ID%"$PASS" //$IP 'powershell.exe -inputformat none -command " "\"{0:N0}"\" -f ( (Get-ChildItem -Path '"$TDIR_MAIL"' -Recurse | Measure-Object -Property Length -Sum ).Sum / 1GB)"' |sed '/^\s*$/d'` echo "Lotus Total User Inbox MAIL SIZE in GB = $FULL_SIZE_MAIL" >> $TEMP_HOLDER #Full size of Lotus ARCHIVE Folder only FULL_SIZE_ARCH=`winexe -U $DOMAIN/$ID%"$PASS" //$IP 'powershell.exe -inputformat none -command " "\"{0:N0}"\" -f ( (Get-ChildItem -Path '"$TDIR_ARCH"' -Recurse | Measure-Object -Property Length -Sum ).Sum / 1GB)"' |sed '/^\s*$/d'` echo "Lotus User's ARCHIVE Folder SIZE in GB = $FULL_SIZE_ARCH" >> $TEMP_HOLDER echo "---------------------------------------------- Lotus Users List whose inbox is exceeding 5 GB" >> $TEMP_HOLDER #Only Top users exceeding 5GB winexe -U $DOMAIN/$ID%"$PASS" //$IP 'powershell.exe -inputformat none -command "Get-ChildItem -Path '"$TDIR"' | Where-Object {$_.length -gt 5GB} | Sort-Object -descending -Property Length | Format-Table Name,@{name='"'"'Size GB'"'"';expression={$_.length/1GB};FormatString='"'"'N1'"'"'}"' | sed -e "$DEL_LINE" | sed '/^\s*$/d' |nl >> $TEMP_HOLDER echo " $FOOTER" >> $TEMP_HOLDER # Display result by cat cat $TEMP_HOLDER # Send email sendemail -u "$MSG_SUB" -o tls=yes -s smtp.gmail.com:587 -t $ADMINMAIL1 -xu $GMAILID -xp $GMAILPASS -f $GMAILID -o message-file=$TEMP_HOLDER -o message-content-type=text
Result of above script …
PowerShell Get Folder / File ACL list
Get-Acl c:\temp | select -Expand Access
Sample Result:
PS C:\> Get-Acl c:\temp | select -Expand Access FileSystemRights : FullControl AccessControlType : Allow IdentityReference : BUILTIN\Administrators IsInherited : True InheritanceFlags : None PropagationFlags : None FileSystemRights : 268435456 AccessControlType : Allow IdentityReference : BUILTIN\Administrators IsInherited : True InheritanceFlags : ContainerInherit, ObjectInherit PropagationFlags : InheritOnly FileSystemRights : FullControl AccessControlType : Allow IdentityReference : NT AUTHORITY\SYSTEM IsInherited : True InheritanceFlags : None PropagationFlags : None FileSystemRights : 268435456 AccessControlType : Allow IdentityReference : NT AUTHORITY\SYSTEM IsInherited : True InheritanceFlags : ContainerInherit, ObjectInherit PropagationFlags : InheritOnly FileSystemRights : ReadAndExecute, Synchronize AccessControlType : Allow IdentityReference : BUILTIN\Users IsInherited : True InheritanceFlags : ContainerInherit, ObjectInherit PropagationFlags : None FileSystemRights : Modify, Synchronize AccessControlType : Allow IdentityReference : NT AUTHORITY\Authenticated Users IsInherited : True InheritanceFlags : None PropagationFlags : None FileSystemRights : -536805376 AccessControlType : Allow IdentityReference : NT AUTHORITY\Authenticated Users IsInherited : True InheritanceFlags : ContainerInherit, ObjectInherit PropagationFlags : InheritOnly PS C:\>
Delete Files Older than 1 month BUT names must be starting with refere or dynamic
Get-ChildItem -Path $path -Recurse -File | where-object {$_.name -like 'refere*' -or $_.name -like 'dynamic*'} | Where-Object {$_.LastWriteTime -lt (get-date).AddMonths(-1)} | Remove-Item -recurse -Force -WhatIf
Display FILES according to SIZE
Display files above then 10GB in size and sort
powershell.exe -inputformat none -command "Get-ChildItem -Path \\FILE_SERVER\SHARED_FOLDER\ | Where-Object {$_.length -gt 10GB} | Sort-Object -descending -Property Length | Format-Table Name,FileSize"
Display Files Greater than & Less than particular size
powershell.exe -inputformat none -command "Get-ChildItem -Path \\agpinf01\e$\archive | Where-Object {($_.length -gt 10GB) -and ($_.length -lt 20GB)} | Sort-Object -descending -Property Length | Format-Table Name,FileSize"
Regard’s
Syed Jahanzaib