Wednesday, February 13, 2013

Powershell Script DIY: removing items based on date


Powershell Script DIY: removing items based on date
Warning: This DYI is potentially damaging, be absolutely sure you want to do this and you test it in a sandbox first.
With that being said, today we are going to remove items from a directory basted on their date.  The first thing we are going to do is define the directory.  We start with “dir”:

                Get-ChildItem

We need to define the location:

                Get-ChildItem 'C:\Temp\'

Now we use the –recurse operator.  Recurse is short for recursive which, plainly put means serch everything in subdirectories too.  So if you don’t want it to do this, skip this next step:

                Get-ChildItem 'C:\Temp\'-recurse 

Now that we have defined the scope of the commands, we need to use the pipe operator in order to tell it “now that you have gotten c:\Temp AND everything in every folder it contains do this”:

                Get-ChildItem 'C:\Temp\'-recurse  |

In order to diferenciate between files, we need to give Powershell a conditional statement.  We begin this with “where”:

                Get-ChildItem 'C:\Temp\'-recurse  | where

When you use a conditional statement, such as foreach-Item or Where, we need to encapsulate the statement itself in curley brackets {}:

                Get-ChildItem 'C:\Temp\'-recurse  | where {}

Because we want to remove old items we are going to use the get-date command:

                Get-ChildItem 'C:\Temp\'-recurse  | where {(get-date)}

We encapsulate this in parantheses as well in order to say that we are not getting the date from system time.  Next we define what date we want to get, which is the file creation time time:

                Get-ChildItem 'C:\Temp\'-recurse  | where { ((get-date)-$_.creationTime)

Remember the -$_. The – indicates what to get, the $_ indicates it is a list of items and the . belongs to .creationTime.  Moving along we encapsulated all of that within another set of parentheses to say that is a group that has a specific output, creation time. We need to then do something with it to indicate the length of time that has passed since it was created.  This is where we use .days:

                Get-ChildItem 'C:\Temp\'-recurse  | where { ((get-date)-$_.creationTime).days

Now here is where we accually select old items with the –ge operator.  Remember if the file was created today, then its age is 0.  For our purpouses we will say we want to select all files not created today:

                Get-ChildItem 'C:\Temp\'-recurse  | where { ((get-date)-$_.creationTime).days -ge 0

Now that we have selected the files that we want we need to add an additional command, which means an additional Pipe operator:

                Get-ChildItem 'C:\Temp\'-recurse  | where { ((get-date)-$_.creationTime).days -ge 0} |

Now because we want to remove we use the remove-item command, which was the same as del in DOS:

                Get-ChildItem 'C:\Temp\'-recurse  | where { ((get-date)-$_.creationTime).days -ge 0} | remove-item

Remove-Item has a couple of switches in it that you can use, for our purposes we are going to use the –force and the –recurse switches to tell it to delete EVERYTHING selected and to do it nondescrimitory:

                Get-ChildItem 'C:\Temp\'-recurse  | where { ((get-date)-$_.creationTime).days -ge 0} | remove-item -force –recurse

And there you have it!  As usual please add your comments below and I fully encourage you to share this with your colleagues.  Also that extra few clicks to +1, Like, Tweet, linkedin Goes a long way for me!

Sources: Microsoft Scripting guy http://preview.tinyurl.com/37ljrya, Myself

Powershell Script DIY: Use a Variable to Refer to a User System Folder


     One of the problems I run into when writing scripts is the confusion when addressing dynamic and system specific folders.  By dynamic folders, I mean the ones that are specific to each user such as the desktop, my documents, app data, ect.  As you may well know, I like to work with variables as they tend to simplify things when used properly.  We start by defining our variable with the "$":

$desktop =
Next we are going to tack on the [Environment] definition this is going to state that the value is indeed an environmental variable.

$desktop = [Environment]::

You may notice the :: after [Environment].  This is necessary to signify that we are going to specify a part of the environment, particularly, the path of the desktop directory.  We are going to do this with GetFolderPath.

$desktop = [Environment]::GetFolderPath

We now specify what variable, for our purposes we are of course gong to use the desktop.  This needs to be encapsulated in parentheses, and in double quotations to treat it like text.

$desktop = [Environment]::GetFolderPath("Desktop")

Now that you have the complete command, what exactly does it do? It starts by saying The Variable ($) Desktop is equal to (=) the Desktop Path ("Desktop") which you can get the path from (::GetFolderPath)
the working environment ([Envirment]).

This operation can be done using the following folders, and remember they must be typed exactly as you see here:

Desktop
Programs
Personal
MyDocuments
Favorites
Startup
Recent
SendTo
StartMenu
MyMusic
DesktopDirectory
MyComputer
Templates
ApplicationData
LocalApplicationData
InternetCache
Cookies
History
CommonApplicationData
System
ProgramFiles
MyPictures
CommonProgramFiles

As always I fully encourage comments.  There is always a better way to do something

Tuesday, February 12, 2013

Powershell Script DIY: Error establishing connection when pulling HTML


I noticed on an early blog post titled “Downloading HTML code from the internet using powershell” I failed to touch on HTTPS connections with untrusted certificates.  Occasionally you may run up on a website that has an untrusted certificate that gives you this when you try to navigate to it using internet explorer:


This is because of a problem with the certificate being unverifiable.   Should you attempt to run a script that refers to this address it will return this error:

Exception calling "DownloadString" with "1" argument(s): "The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."
This can be alleviated by using the following line of code before you query the web page:

 [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

As always, do not query web pages unless you know the contents and do not run security code unless you know its effect.  Please leave you comment below!


Source: Daniel Richnak http://stackoverflow.com/questions/6781433/how-to-ignore-ssl-certificate-is-signed-by-an-unknown-certificate-authority-prob

Monday, February 11, 2013

Powershell Best Practices: Commenting in Powershell. While optional, Its highly encouraged.


 This post is more of a “best Practice” then a “How To,” although, It does contain some how elements.  Commenting in any programming language is in important function, and even more so in Powershell due to the fluid nature of scripting.  While not officially defined, I like to think there are 4 types of comments:

Header: This includes the authors name, the creation / last modification date, and the purpose.  This is important as a script can be renamed a number of times, but you need to know what your published script does.  Some companies even mandate this set of comments as a way of tracking employs work.

# Author: John Doe
#Date Created: 1/1/2010
#Date Last Modified: 2/2/2012
#Purpous: Provide an example of commenting out a header


Explanation:  Code is confusing.  Very confusing.   When a large script is written, it is good to explain blocks of commands so that your successor can come in and make alterations if needed.

#this next line of code sets your working directory to “c:\temp”
Set-Location “c:\temp


Credit:  This is like citing your work on a paper.  It’s not only honest but necessary if the code needs to be manipulated. If no author is presented, verify the code and put down the web address where you found it. Remember, DO NOT USE CODE YOU CANNOT EXPLAIN.  Period.

#this next block of code was provided by Jane Doe via Janedoescripting.com.  Her email address is doe.jane@janedoescripting.com

Temporary editing:  When you’re working with code and are not sure if your modifications are right, comment out the original section and start from scratch.  This will keep you from getting lost in your purpose and provides you with the opportunity to revert to the original block of commands.

#remove-item “c:\temp\*.*
Remove-item “c:\temp\*.log

With that being said the two commands you need to know are # and <# #>.  # comments out 1 line in a script and is best used when you only have one line to comment.

#remove-item “c:\temp\*.*

This will make Powershell ignore your command so long as # precedes it.  Block commenting is used for most everything else.  Simply Precede the block of commands with <# and succeed it with #>:

<#
Set-Location “c:\temp
$foo = “foo.txt
#>

Do you have anything to add? Do you have corrections or Kudo’s?  Please leave a comment below! And remember, a share and a +1/like/tweet go a long way!

Powershell Script DIY: Adding a line at the begining of a file


Today we are going to add a header to our file, foo.txt.  This can be useful for adding a header to a CSV file, or just adding a title to your output for easy reference.  Whatever your reasons you always need to start by Setting your location and defining variables:

Set-Location “C:\Temp

$fooaltered = “fooaltered.txt
$H = "the title is foo"
$I = Get-Content “foo.txt”

Notice the Get-Content command in the definition for $I?  This is necessary to grab the contents of foo.txt and not the actual file itself.  Remember, you must encapsulate the actual object or value in quotations, but any command prior to that does not get the quotes.
Next we need to use the Set-content command

Set-Content

We tell powershell what variable we want to set the content to:

Set-Content $fooaltered

And we use the nifty –value switch to tell powershell that we are adding more than just one set of data:

Set-content $fooaltered –value

Now we use the variables $H and $I that we defined earlier to define the content of fooaltered.txt.  It is important to note that when using multiple values in this manner you need to separate them with a comma and a space:

Set-Content $fooaltered –value $H, $I

If you want to limit the size of your file to a certain number of lines, you can use the [x…y] definition where x and y are line numbers.  This is useful if you need to keep the file a certain size, or number of lines:

Set-Content $fooaltered -value $H, $I[0..5000]

Your end result should be:

Set-Location “C:\Temp

$foo = "foo.txt"
$fooaltered = “fooaltered.txt
$H = "the title is foo"
$I = Get-Content $foo
Set-Content $fooaltered -value $H, $I[0..5000]

As always if you have a correction or something to add, Please feel free to post below!

Powershell Script DIY: Creating Variables


     The most important thing you do in Powershell scripting is setting variables.  A variable is any value that you need to refer to later.  It can be a location, a file name, a specific number, or anything you could possibly imagine! When done incorrectly, you can end up with a messy script that no one but the most attentive can step through.  Variables are always lead by a $, and can be any combination of letter and number characters.  While you can name your variable anything you want: $bobwehadababyitsaboy, its best practice to have a naming convention in place.  A naming convention is a standardized system of assigning names such as: FirstnameLastnamebirthyear or MakeModelYear.  These two examples would look like

JohnDoe1995
And
ToyotaCamery1994

Once you decide on a naming convention it is time to define your variable “foo.” We start with the $

$

And add the variable name:

$foo

Now a variable on its own is useless unless we assign a value, so we tell powershell that foo is equivalent to foo.txt in the current directory.  The = sign is used to say “is” and the quotation is to say “this value.” It is important to remember that the type of quotation is important as double quotes tell Powershell to treat the string as text and single quotes tell it to literally treat it as text.  To clarify, placing a variable in double quotes will return the value of the variable and single quotes will return the variable name as you typed it.:

$foo = “foo.txt”

Until you say otherwise, or close the session, the value of $foo is forevermore “foo.txt

As always, If you have a correction, or something to add, please post a comment below!

Powershell Script DIY: The easy command: Set-Location


     Setting your location is easy, and when done correctly, can give you a proper entry into the world of scripting. For this exercise we use the Set-Location command.

Set-Location

As with every Set command you need to set the value.  The value must always be encapsulated in quotations of some kind. The type of quotes are important.  Double " quotes are for normal non-literal use.  that is, if you put a variable in there, then the variable value will appear.  Single quotes tell Powershell to take the string literal, that is the variable itself will appear in the string, not its value:

Set-Location “c:\temp


As always, If you have anything to add, Post it below!

Edit: I had been misinformed on the use of the two kinds of quotation, this has been corrected.