PowerShell is a cool feature that makes the life of System Administrator easier.
It makes life easier because it will automate processes or procedures.
When would you automate a process?
If you find yourself in a situation where you always keep repeating the same thing, it’s a good sign that you need to automate the process. Unless you really love doing it and you don’t get annoyed doing it all over again and again, day in and day out.
If there’s a need also to consolidate or do a clean-up of hundreds and thousands of files, automating the process should be a good option. Not only it makes the work easier and is done quickly. Automating the process is not prone to human error.
But you need to do some trial test of the script to make sure it works as you expected.
On this example will consolidate files on a particular folder and sort the files by year and automatically create a folder by year. And move the files to the folder based on its year.
This would be good, if you have log files that have never been clean up for years and years.
Archiving log files is a good practice because you just don’t know when you will need it.
Since the title is Beginning PowerShell from Step 1 to Step 1, we will create a script to move files to a folder base on its year and hope I will be able to explain it on the beginner's point of view.
I have two folders on my d drive, called LogFiles and ArchiveFolder.
If you need to do some testing with this code, those two folders must exist on d drive or just change it as per your need.
Create a variable and assign a value.
$xSourceFolder = "d:\LogFiles" (LogFiles directory is on my D drive, change as necessary)
Variable in PowerShell should have a “$” dollar sign prepended to its variable name.
$xSourceFolder is a variable that holds “d:\LogFiles”.
String value is enclosed in quotation marks “string_value”.
“d:\LogFiles” is a string value assign to $xSourceFolder.
Next command is:
$strItems = Get-ChildItem -Path "$xSourceFolder\*.*" -include *.log, *.txt
$strItems is a variable that will hold the value of the Get-ChildItem command.
Get-ChildItem is called PowerShell cmdLets.
Find out more about power shell cmdLets click links below:
Using the Get-Item Cmdlet and other CmdLet on PowerShell
http://technet.microsoft.com/en-us/library/ee176851.aspx
http://technet.microsoft.com/en-us/library/hh849788.aspx
To get help or get syntax about a cmdlet, type this command below:
Get-help Get-Item -Example
Command below will get all items on the specified path and assign values to “$strItems”.
$strItems = Get-ChildItem -Path "$xSourceFolder\*.*"
“*.*” is a wildcard character which means anything dot anything or it means any filename and any filename extension.
Since there is a need to filter which files for processing, the “ –include” parameter is used which tells the PowerShell to just include the files specified.
$strItems = Get-ChildItem -Path "$xSourceFolder\*.*" -include *.log, *.txt
The filter parameter is –include *.log, *.txt which basically will process for any filename which has “.log” extension and any filename which has “.txt” extension.
In this example we assume that there are files in “d:\LogFiles” folder which contains log files and txt files which have been there for years and years.
To process all the files, “for loop” statement is needed.
Loop as it means literally is like a circle.
In programming language “For Loop” is used to process files and execute commands inside “for loop” statement until a condition is meet and it will exit or stop its process.
So if the condition is not meet it will go to a circle, in which it will go for an eternal loop and crash the application or the whole system.
In PowerShell “For Loop” has this syntax:
foreach (some statement)
{ - means begin
#additional codes
} – means end
If either one of the curly braces is missing it will result to an error.
If there is only begin and the end statement is missing it will result to an error.
Likewise if there is only an end statement and begin statement is not present it will also result to an error.
Literally, anything that is under the sun which has a beginning will also have its end in due course. So have faith and hold on to the prize on High.
Curly braces is important in for loop statement, good practice is to type two curly braces { } and just press enter between the curly braces and enter more codes.
Conditional statements are enclosed in open and close parenthesis ( ).
foreach (conditional statements)
{ #--begin
#additional codes for processing
#-- used for labelling or comments on PowerShell
#-- will not be executed or process
#--use comments in order not to forget what the function or code is doing
#--makes life easier for debugging or troubleshooting
}#--end
Purpose of the function below, is to loop or check through the log and text files, check the year of each file.
And move the file to each corresponding year in a folder.
Name of the directory will be the “Year” in “YYYY” format, if the directory does not exist create the directory and move the file. If the directory exists already, just move the file to the directory.
Actual command statement will be:
foreach ($item in $strItems) { #begin for loop statement
$xStr = $item.LastWriteTime.ToString("yyyy")
Write-Host $xStr
$var_Path = Test-Path "d:\ArchiveFolder\$xStr"
write-host $var_Path
switch ($var_Path)
{ #-- -begin switch statement
False { Write-Host "Directory Does not exist"
new-item “d:\ArchiveFolder\$xStr” -itemtype directory #will create a new directory
Move-Item "$item" "d:\ ArchiveFolder\$xStr"
}
True {
write-Host "Directory Exist, just move the file "
Move-Item "$item" "d:\ ArchiveFolder \$xStr"
}
} #-- -end of switch statement
} #-- end of for loop statement
$strItems = Get-ChildItem -Path "$xSourceFolder\*.*" -include *.log, *.txt
foreach ($item in $strItems)
$strItems --holds the values or the data on path specified
foreach --statement will process one by one the data on $strItems
$xStr = $item.LastWriteTime.ToString("yyyy")
$xStr is a new variable that will hold the year value for each item
$item.LastWritem.ToString(“yyyy”) #-- will convert the data to string
Please check this links below from TechNet to find out more on PowerShell String formatting.
http://technet.microsoft.com/en-us/library/ff730954.aspx
http://technet.microsoft.com/en-us/library/ee692801.aspx
Write-Host $xStr
Write-Host in PowerShell will write a string to the console.
If just trying to get your hands wet on PowerShell, or if you’re in debugging process Write-Host will help.
It will write the value to console, and you will be able to check whether the variable holds the value or the output you’re expecting.
$var_Path = Test-Path "d:\ArchiveFolder\$xStr"
$var_Path will hold a Boolean value which means it will be either True or False.
Test-Path on PowerShell will check if the directory exists on a given Path, it will return True if the directory exists and False if it is not able to find the directory.
write-host $var_Path
Just for testing Purposes if Test-Path is telling the truth.
For test purposes, good if you’re just trying to see how the program is executing. It will return true or false only. If the output is “Trulse” contact Microsoft PowerShell engineers.
To process conditional statements, you can use “If then else” statement, but I prefer to use Switch statement.
If you have time, you can experiment with “If then else” and you will realize “Switch” is much more preferable.
switch ($var_Path) #--begin evaluate data
{ #-- begin of switch statement
#If $var_Path is False codes below will be process
False {
Write-Host "Directory Does not exist"
new-item d:\LogFiles\$xStr -itemtype directory #--will create new directory
Move-Item "$item" "d:\LogFiles\$xStr" #--will move files to the new directory
}
#if $var_Path is True codes below will be process
True {
write-Host "Directory Exist, just move the file "
Move-Item "$item" "d:\LogFiles\$xStr"
}
} #-- end of switch statement
If you plan to use this on production, and you’re not sure how the codes is being executed.
Please do some testing, replace the variable paths and check the output whether it works as you expected.
Please don’t use the code, if you really don’t know what you’re doing.
PowerShell can make your life easier but it can also mess up your life if you don’t know how to use it.
If you want to do some testing and you don’t have log or text files from previous years, you can make use of any document, PDF, Excel or just anything then rename the extension to “.log” or “.txt”.
Or you can make use of Linux touch command to modify file date.
If you just want the whole code, copy and paste this code snippet:
===========Start of Code Snippet===============
$xSourceFolder = "d:\LogFiles"
$strItems = Get-ChildItem -Path "$xSourceFolder\*.*" -include *.log, *.txt
foreach ($item in $strItems) {
$xStr = $item.LastWriteTime.ToString("yyyy")
Write-Host $xStr
$var_Path = Test-Path "d:\ArchiveFolder\$xStr"
write-host $var_Path
switch ($var_Path)
{
False {Write-Host "Directory Does not exist"
new-item "d:\ArchiveFolder\$xStr" -itemtype directory
Move-Item "$item" "d:ArchiveFolder\$xStr"
}
True {write-Host "Directory Exist, just move the file "
write-Host $item
Move-Item "$item" "d:\ArchiveFolder\$xStr"
}
}
}
===========End of Code Snippet===============
Output below is the real output while I was doing this experiment:
2014
False
Directory Does not exist
Directory: D:\ArchiveFolder
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 3/15/2014 11:11 AM 2012
False
Directory Does not exist
d---- 3/15/2014 11:11 AM 2012
2007
False
Directory Does not exist
d---- 3/15/2014 11:11 AM 2007
1998
False
Directory Does not exist
d---- 3/15/2014 11:11 AM 1998
2013
False
Directory Does not exist
d---- 3/15/2014 11:11 AM 2011
False
Directory Does not exist
d---- 3/15/2014 11:11 AM 2011
2012
True
Directory Exist, just move the file
D:\LogFiles\php_error.log
2014
True
Directory Exist, just move the file
D:\LogFiles\readme.txt
2013
True
Enjoy PowerShell!!! Click on the label “PowerShell” below to find out more PowerShell on this blog!!!
Cheers!!!
=====================
Educational App for Android Kids:
https://play.google.com/store/apps/details?id=com.letsmultiply
Linux Android App cheat sheet:
https://play.google.com/store/apps/details?id=com.LinuxMobileKit
Hi
ReplyDeleteI'd like to say thanks for providing this tutorial. If it wasn't for this tutorial, I would have given up trying to learn PowerShell - literally. Thats because I found the Microsoft web-links too in-depth. This was just perfect for me. If I have any critism, I would ask that you put the code sections in using a different font style otherwise total beginners might struggle. I liked it as it was though, as it made me think more carefully about which brackets the code needs to be tucked into.
Extreme thanks again - I look forward to any more I can find like this one.
Kind Regards
Matt
Thanks Matt, glad to know that it helps you. :)
ReplyDeleteYou can click on the label "PowerShell" to check all PowerShell post on this blog.
ReplyDelete