PowerShell: Copying Individual Files and Renaming Duplicates

Posted by Kris Powell

Jan 8, 2015 1:28:32 PM

There are many factors to consider when copying files within a script.kris_resized

In many instances, we check for the existence of a file and only copy the file if it does not exist. Sometimes we only copy if it’s older/newer than a certain file.  Sometimes we only copy if the file sizes are different...and so on and so forth.

I’m sure that you get the idea. There are many things to consider.

For this particular case, I wanted to keep all copies and rename any duplicates sequentially. I will be using Copy-Item to get this done.

Copy-Item

Normally, when using Copy-Item, you’ll find that it will overwrite any destination files. It will not create any nonexistent folders in your destination file path.

For example, if you try to copy the source file to a new location that doesn’t exist yet, you will see a similar error:

Copy-Item-Fails-Nonexistent-Directory

In this case, the C:\Temp\File.txt file exists but the subdirectory does not, as it mentions in the error above.

The only way to get Copy-Item to create the subdirectories if they don’t already exist is to copy a directory recursively. Unfortunately, it will not work with individual files, so it is out of the scope for this post.

Test-Path and New-Item

One of the simplest ways to get the nonexistent directories created when copying individual files is to test for missing files and manually create the file before you copy (similar to unix/linux “touch” command).

In order to verify if a file already exists, we will use the Test-Path cmdlet. Test-Path can verify if a file or folder exists. When using Test-Path, items that exist will return $true whereas items that do not exist (or cannot be verified) will return $false:

Powershell-Test-Path-Examples

Once we've verified that a file doesn't exist, we can use New-Item to create a placeholder for the file we're about to copy. Unlike Copy-Item, New-Item can create the nonexistent directory structure when creating new files.

Copying files and creating any nonexistent subdirectories

Here’s an example of creating the destination file before copying (in order to create the destination file’s directory structure):

#############################################################################

$SourceFile = "C:\Temp\File.txt"
$DestinationFile = "C:\Temp\NonexistentDirectory\File.txt"

If ((Test-Path $DestinationFile) -eq $false) {
    New-Item -ItemType File -Path $DestinationFile -Force
} 

Copy-Item -Path $SourceFile -Destination $DestinationFile 

#############################################################################

Breaking it down:

First, we test if $DestinationFile exists by using Test-Path. If the result of that Test-Path is false, we create an empty file by using the New-Item cmdlet.  

The New-Item cmdlet will create our file. Using -Force here tells New-Item to create all the directories necessary for that particular file.

Finally, we are able to successfully use the Copy-Item command to copy the $SourceFile to the newly-created $DestinationFile.

As awesome as this is, it only gets us partially there.  The normal behavior for Copy-Item will overwrite the destination file (with or without -Force). We’re trying to preserve all files and create duplicate destination files instead of overwriting.

Copying individual files and renaming any duplicates

Here is a simple way to copy a file from one location to another while preserving all destination files. We  increment the destination file names:

#############################################################################

$SourceFile = "C:\Temp\File.txt"
$DestinationFile = "C:\Temp\NonexistentDirectory\File.txt"

If (Test-Path $DestinationFile) {
    $i = 0
    While (Test-Path $DestinationFile) {
        $i += 1
        $DestinationFile = "C:\Temp\NonexistentDirectory\File$i.txt"
    }
} Else {
    New-Item -ItemType File -Path $DestinationFile -Force
}

Copy-Item -Path $SourceFile -Destination $DestinationFile -Force

#############################################################################

Breaking it down:

We test if the path $DestinationFile exists by using Test-Path. We then check if the file name already exists.

If $DestinationFile doesn’t exist, it will create the file and then copy the source over the destination file.

If $DestinationFile does already exist, it will jump into a While loop. It will modify the DestinationFile name by incrementing part of the name, testing each modified name until it finds a name that doesn’t match an existing file.

If File.txt doesn’t exist, it will create File.txt first. Subsequent runs will create, File1.txt, File2.txt, File3.txt and so forth.

Keep in mind that copying large or numerous files will result in increased disk usage, so be sure to keep an eye on your utilization.

Disclaimer and side notes

Use these scripts at your own risk. Be sure you understand what you're doing before using these in a production environment. As always, feel free to modify these to suit your environment.

I realize that there are many ways to tackle the issues above. In fact, the latest estimates place the possibilities at around 1.2 bajillion, though scientists predict even greater numbers.

Additional resources and tools for copying/moving/deleting files are also available, such as one of my favorite tools for copying: Robocopy.

Good luck!

Read More

Topics: powershell

Powershell: Silently Change Firefox Default Search Providers

Posted by Kris Powell

Dec 11, 2014 11:26:00 AM

By now, I’m sure many (if not all) of you are aware that the latest version of Firefox modified the default kris_resizedsearch provider to be Yahoo for all U.S. customers.

It’s simple enough to change on an individual basis for any particular user (instructions here).  As system administrators for our various organizations, the issue that we often run into is making sweeping changes for many machines all at once.

Enter PDQ Deploy 4

For users of PDQ Deploy 4, this script is available as a package in our Package Library. The package is called, “Mozilla Firefox - Set Google as Search Engine.” We’re providing this as a package for all PDQ Deploy 4 users. This includes those that use the Free version of our software.


If you’re not familiar with PDQ Deploy, you should drop what you’re doing right now and go grab it.

Seriously, though, it’s a snap to setup and to deploy software silently to all the users in your organization.

Until this latest version, the preference option browser.search.selectedEngine is what was used to set the default search engine. There are many other preferences that can be configured and, indeed, are centrally configured in organizations that utilize Firefox. It is fairly straightforward to change different preferences. Here is a quick link to more information on the many configuration settings available in Firefox.

With the new version of Firefox, when you change your default search engine provider, the setting is no longer stored with the other configuration settings. The value is stored as a hashed value in a json file called search-metadata.json. It is created in the active Firefox profile for the current user. These settings may be changed in subsequent releases of Firefox.


Silently changing the default search engine

This is the PowerShell script that we use to modify the search provider of Firefox:

#############################################################################

$Provider = "Google"

$Disclaimer = "By modifying this file, I agree that I am doing so only " $Disclaimer += "within Firefox itself, using official, user-driven search " $Disclaimer += "engine selection processes, and in a way which does not " $Disclaimer += "circumvent user consent. I acknowledge that any attempt " $Disclaimer += "to change this file from outside of Firefox is a malicious " $Disclaimer += "act, and will be responded to accordingly."
# The above disclaimer is required verbatim. Yeah... we think it's silly too.  
$Pattern    = "{`"\[global\]`"\:{`"current`"\:`"(.*)`",`"hash`"\:`"(.*)`"}}"
$Encoding   = [System.Text.Encoding]::UTF8
$Hasher     = New-Object ([System.Security.Cryptography.SHA256]::Create())

Get-ChildItem "$env:public\..\*\AppData\Roaming\Mozilla\Firefox\Profiles\*" | 
    Where-Object { $_.PSIsContainer } | ForEach-Object {

    $ByteData   = $Encoding.GetBytes($_.Name + $Provider + $disclaimer)
    $HashResult = $Hasher.ComputeHash($ByteData)
    $Result     = [System.Convert]::ToBase64String($HashResult)
    $File = "$($_.FullName)\search-metadata.json"
    $Data = "{`"[global]`":{`"current`":`"$Provider`",`"hash`":`"$Result`"}}"

    If (-Not (Test-Path $File)) {New-Item -Path $File -ItemType file}

    (Get-Content $File) | Foreach-Object {
        If ($_ | Select-String -Pattern $Pattern) { 
            $_ -replace $Pattern, $Data
        } Else {
            $data 
        } 
    } | Out-File $File -Encoding utf8

    If ((Get-Content $File) -eq $Null) {
        $Data  | Out-File $File -Encoding utf8
    }
}
#############################################################################

By utilizing the System.Security.Cryptography namespace in .NET, we calculate a SHA-256 hash from the combined values of the $Disclaimer, the firefox profile name and the name of the provider you wish to configure. We store the value of the result to the search-metadata.json in the current user’s firefox profile folder.

After running the script for any given machine, the change will be reflected when Firefox is restarted.

You can use any installed search provider as a value to update. By default in the US-version of Firefox, these values include:

  • Amazon.com
  • Bing
  • DuckDuckGo
  • eBay
  • Google
  • Twitter
  • Wikipedia (en)
  • Yahoo

This script will update all user profiles on a given machine, so long as the firefox profile folder exists for a user. The profile gets created when a user runs Firefox for the first time.

That’s it.

It’s not a terribly long script, though it does certainly look fancy.

Try it out on a test machine and see if it works for you. You can decide if you want to use this in your organization. If you decide you would like to use this, we recommend the easy method of using this script.


The easy way

Install PDQ Deploy (4 or later) and grab our package and simply deploy it to all your users in your organization. If you have any questions along the way, we have a large variety of helpful videos - link.

The harder way

Take this script directly and manipulate it to run for all machines in your organization. This option is for the more advanced user who is familiar with scripting languages such as PowerShell.


It goes without saying that you should use this script at your own risk. 

Good luck!

 
Read More

Topics: powershell

PowerShell: Text-to-Speech Examples

Posted by Kris Powell

Oct 30, 2014 3:53:00 PM

This is a fun way to utilize Text to Speed (TTS) with PowerShell for Halloween. This is a fun little prank you can use to turn your users kris_resizedcomputers into "haunted" computers as long as they've got their speakers on. 

We use the cmdlet Add-Type to add a .NET framework type to a PowerShell session. We can then instantiate a SpeechSynthesizer object to turn our text into audio output. It’s pretty exciting.

The easiest way to try this is like so:

Add-Type -AssemblyName System.speech
$speak = New-Object System.Speech.Synthesis.SpeechSynthesizer
$speak.Speak('Hello...')

You can even jazz it up a bit by modifying the speed of speech by modifying the rate property of the object.  Here’s a good resource to see the different properties/methods of this object - link (scroll towards the bottom).

Add-Type -AssemblyName System.speech
$speak = New-Object System.Speech.Synthesis.SpeechSynthesizer
$tts.Rate   = -5  # -10 to 10; -10 is slowest, 10 is fastest
$speak.Speak('Hello...')

From there, we can start having some fun. For example, we could place a list of phrases into an array or a separate text file and pull a phrase at random to be synthesized. Be sure to choose which method you’d like to use.

Add-Type -AssemblyName System.speech
$tts = New-Object System.Speech.Synthesis.SpeechSynthesizer

# Importing from text file
$PhraseLocation = "C:\SomeFolder\ListOfPhrases.csv"
$Phrase         = (Get-Content $PhraseLocation) | Get-Random

# Using an array
$Phrase2 = @("I'm a robot.", 
    "Help, I'm stuck in the machine!", 
    "What are you doing, $env:USERNAME") | Get-Random

$tts.Rate   = 0  # -10 is slowest, 10 is fastest
$tts.Speak($Phrase)

Hopefully, this gives you some fun ideas for Halloween tomorrow!

Bonus:

Those of you who want to experiment with even more control over TTS can make use of Speech Synthesis Markup Language (SSML).

Here's an example:

Add-Type -AssemblyName System.speech
$tts = New-Object System.Speech.Synthesis.SpeechSynthesizer

$Phrase = '
<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" 
    xml:lang="en-US">
    <voice xml:lang="en-US">
    <prosody rate="1">
        <p>Normal pitch. </p>
        <p><prosody pitch="x-high"> High Pitch. </prosody></p>
    </prosody>
    </voice>
</speak>
'
$tts.SpeakSsml($Phrase)
Read More

Topics: powershell

PowerShell: Zip up files using .NET and Add-Type

Posted by Kris Powell

Oct 16, 2014 10:00:00 AM

I recently came across a need to zip up some files prior to copying them over the network. Normally, I’d simply use kris_resizedanother tool such as WinZip or 7zip, but I thought I’d like to see how PowerShell could handle it.

There are many tools out there to help you with this (7zip cli, PowerShell community extensions, etc). They’re not included with Powershell, so I decided to try and make use of the tools we have at hand.

I decided to go with a quick way to zip up files by leveraging .NET and using the cmdlet Add-Type

Zipping files with PowerShell

Note: This requires .NET 4.5 and Powershell 3+

This example script is pretty straightforward and simple.  It makes use of the System.IO.Compression.Zipfile class that was included with .NET 4.5.  We make use of the PowerShell cmdlet Add-Type to add a Microsoft .NET Framework type to the PowerShell session.  This allows to leverage .NET in our PowerShell scripts.

#############################################################################
#
# -SourceFolder    = The folder with the files you intend to zip
# -DestinationFile = The zip file that you intend to create
# -Compression     = The type of compression you'd like to use:
#                         Optimal (default option)
#                         Fastest
#                         NoCompression
# -IncludeParentDir = Setting this option will include the parent directory
#
#############################################################################

$SourceFolder    = "C:\temp\Zip This Folder"
$DestinationFile = "C:\temp\NewZip.zip"
$Compression     = "Optimal"  # Optimal, Fastest, NoCompression

Zip-Directory -DestinationFileName $DestinationFile `
    -SourceDirectory $SourceFolder `
    -CompressionLevel $Compression ` #Optional parameter
    -IncludeParentDir #Optional parameter

function Zip-Directory {
    Param(
      [Parameter(Mandatory=$True)][string]$DestinationFileName,
      [Parameter(Mandatory=$True)][string]$SourceDirectory,
      [Parameter(Mandatory=$False)][string]$CompressionLevel = "Optimal",
      [Parameter(Mandatory=$False)][switch]$IncludeParentDir
    )
    Add-Type -AssemblyName System.IO.Compression.FileSystem
    $CompressionLevel    = [System.IO.Compression.CompressionLevel]::$CompressionLevel  
    [System.IO.Compression.ZipFile]::CreateFromDirectory($SourceDirectory, $DestinationFileName, $CompressionLevel, $IncludeParentDir)
}

#############################################################################
 
Read More

Topics: powershell

PowerShell: Sending Email (with Gmail example)

Posted by Kris Powell

Oct 9, 2014 10:55:00 AM

It’s late on a Friday night. Like most people, you have somewhere else you would rather be. Instead, you are stuck atkris_resized work because you completely forgot about some scheduled maintenance that has to be done that night.

You’re familiar enough with PowerShell to make some scripts to take care of the maintenance, but you’re worried about the off-chance that one of the scripts fails or you’re worried that something could go wrong.

Wouldn’t it be great if you could start your scripts and configure them to email you the results? You could still get out, enjoy your Friday night and rest assured that you’re scripts are doing their job without you losing yours!

(Disclaimer: We do not condone the shirking of any responsibilities that you may have...especially on Friday nights.)

Sending Email with PowerShell

There are a multiple ways to send an email with PowerShell. This is a native cmdlet option that is simple and easy to use. It uses the cmdlet Send-MailMessage.

Send-MailMessage <parameters>

List of available parameters

-Attachments string
    The full path and filenames to be attached to the email.

-Bcc string
    Email addresses that you would like to bcc.

-Body string
   The body of the email message.

-BodyAsHtml
   Indicates that the value of the Body parameter contains HTML.

-Cc string
   Email addresses that you would like to cc.

-Credential PSCredential
   An account that has permission to send the email. The default is the current user.

-DeliveryNotificationOption Option
   Delivery notifications will be sent to the email address specified in the -From parameter.

          None - No notification (default)
          OnSuccess - Notify if the delivery is successful.
          OnFailure - Notify if the delivery is unsuccessful.
          Delay - Notify if the delivery is delayed.
          Never - Never notify.

-Encoding Encoding
   The encoding used for the body and subject. 

-From string
   
The address from which the mail is sent.

-Priority Priority
   
The priority of the email message. Valid values: Low, Normal (default), High

-SmtpServer string
   The name of the SMTP server that sends the email message.

-Subject string
 
  The subject of the email message.

-To string
   
The addresses you wish to send email to. 

-UseSsl
    
Use the Secure Sockets Layer (SSL) protocol to establish a connection to the SMTP server to send email. SSL is not used by default.

Examples of Usage:

Example 1 - Sending a simple email

Send-MailMessage -From “email@yourdomain.com” -To “AnotherEmail@yourdomain.com” -Credentials (Get-Credential) -SmtpServer “smtp.yourdomain.com”

Example 2 - Sending an email from Gmail

Here’s a full example of sending an email via Gmail’s SMTP servers.  It will prompt you for a username and password thanks to (Get-Credential).  The username needs to be <your full gmail address> and password needs to be <your gmail password>, though you could always pipe in a PSCredential and get the same effect.

 

##############################################################################
$From = "YourEmail@gmail.com"
$To = "AnotherEmail@YourDomain.com"
$Cc = "YourBoss@YourDomain.com"
$Attachment = "C:\temp\Some random file.txt"
$Subject = "Email Subject"
$Body = "Insert body text here"
$SMTPServer = "smtp.gmail.com"
$SMTPPort = "587"

Send-MailMessage -From $From -to $To -Cc $Cc -Subject $Subject `
-Body $Body -SmtpServer $SMTPServer -port $SMTPPort -UseSsl `
-Credential (Get-Credential) -Attachments $Attachment

##############################################################################

 Best of luck to you in your emailing endeavors!

Read More

Topics: powershell

Powershell: Get CPU Usage for a Process Using Get-Counter

Posted by Kris Powell

Oct 2, 2014 11:08:00 AM

I was on Stack Overflow not too long ago when I came across a post involving gathering CPU usage bykris_resized percentage that I simply couldn’t pass up. I had to see how PowerShell would handle it.  

I wasn’t disappointed.

After a few revisions, here is a neat way to get the CPU usage of a particular process and have it displayed by CPU percentage.

Be sure to choose between option A or option B. I currently have option B commented out.

#############################################################################
# Option A: This is if you just have the name of the process; partial name OK
$ProcessName = "cpu"

# Option B: This is for if you just have the PID; it will get the name for you
#$ProcessPID = "6860"

#$ProcessName = (Get-Process -Id $ProcessPID).Name
$CpuCores = (Get-WMIObject Win32_ComputerSystem).NumberOfLogicalProcessors
$Samples = (Get-Counter "\Process($Processname*)\% Processor Time").CounterSamples
$Samples | Select `
InstanceName,
@{Name="CPU %";Expression={[Decimal]::Round(($_.CookedValue / $CpuCores), 2)}}
#############################################################################

This makes use of the Get-Counter cmdlet that allows you to get performance counter data for local/remote machines. Let's find out more! The following command will get you a lot of information about all the counter sets that are available to use.

Get-Counter -ListSet *

It's a lot of information. Too much for me, in fact, which is why I usually use the following command. It will get you a list of all the sets of counters that are available to be used:

Get-Counter -ListSet * | Sort-Object CounterSetName | Format-Table CounterSetName

In that list, I see an object called Processor that I'd like to know more information about and which counters are available. I would find out more information like this:

Get-Counter -ListSet Processor

That gets a lot of information. I'd like to see the counters themselves as I would use them with Get-Counter:

(Get-Counter -ListSet Processor).Counter

Now we should have a list that includes "\Processor(*)\% Processor Time" This is what I used to find out the percentage of CPU time for the process. The asterisk (*) in this case is a wildcard grabbing all processes. In the script above, we populate that with the process name that we'd like the know the CPU percentage for.

We also make use of the Get-WMIObject cmdlet to get the total logical processors for the system. This cmdlet is one of the most useful in Powershell and we will likely post many blogs that include Get-WMIObject. Due to how much information can be gleaned from a system by using this cmdlet, we will not go into too much detail at this point in time.

Read More

Topics: powershell

PowerShell: Console Window Tips

Posted by Kris Powell

Sep 25, 2014 11:30:00 AM

kris_resized

If you use PowerShell on a regular or semi-regular basis you may already know these tricks of the trade, but in case you were not aware here are some neat tricks to use in the PowerShell console window.

Tab Completion

Go ahead and type a partial command and press your Tab key. PowerShell magically knows what you’re trying to look for, or at least it will venture an educated guess.

Get-Da<Tab> should autocomplete to Get-Date.

Get-Date - Animated.gif

You can even press Tab (and Shift-Tab) multiple times to cycle through multiple matches.

Get- should autocomplete to multiple commands. Just keep pressing Tab to cycle forwards alphabetically and press Shift-Tab to cycle backwards alphabetically.

Get- - Expansion - Animated.gif

This is great for typing commands more quickly or for trying to type commands that you may not fully remember.

Show Recent Command List

You can show all recently typed commands at a console window by tapping the F7 key. You can then select a command by highlighting it and hitting the Enter key.

F7 - Animated.gif

Scroll Through Recent Commands

You type a command and realize you have a syntax error. Rather than type the command all over again, you can simply tap the Up arrow key to scroll backwards through your recent commands. You can tap the Down arrow key to scroll forwards.

Pause Results On Screen

Have you ever run a command that output more results than fit the screen? Usually, the results will zoom past faster than most of us can read, so we often find ourselves having to scroll to view the results.

No more!

There are two common methods for accomplishing this:

<command> | Out-Host -Paging

<command> | more

Something to note, however, is that it will evaluate the results of a command before outputting them to the console window.

I know that there are many other tips that each of us have come across (aliases, for example). Please feel free to add any suggestions to the comments below so that other readers may be able to benefit from your experience!

 

Read More

Topics: powershell

Powershell: Get-Help

Posted by Kris Powell

Sep 18, 2014 1:48:00 PM

kris_resizedFrom the results of my last Powershell blog post (Get-Command and Get-Member), we should have a list of commands (cmdlets, aliases, etc).

But, how do we know what each cmdlet does?  Or, what if we know how a command works but want to see some examples?

We need some more information about how to use those commands in more detail.  Let’s learn more about the Get-Member cmdlet that we introduced last time by utilizing the tools built into Powershell.

Get-Help

Get-Help displays detailed information about how to use a command and any examples that may exist.

The basic syntax is pretty simple and straightforward.

Get-Help <cmdlet>

In order to find out more about the Get-Member cmdlet, we type:

Get-Help Get-Member

This will give us some basic syntax and usage information about Get-Member as well as a brief description.  Let’s introduce some of the parameters that give us even more information about the cmdlet that you’d like to know more about.

Get-Help <cmdlet> -Examples

This will show usage examples for the cmdlet

Get-Help <cmdlet> -Detailed

This will show more detailed information than the basic syntax

Get-Help <cmdlet> -Full

This shows the entire help file relating to the cmdlet, including details/examples.

Get-Help <cmdlet> -ShowWindow

This will show the full help file for a cmdlet in a new window.  It includes a search box and a settings button to help you configure which information you want displayed.

Get-Help <cmdlet> -Online

This will pull up the online help files for the cmdlet.


Note: If you find that you’re help files seem to be lacking, it’s possible that they’re not fully installed or up-to-date.  In that case, run Powershell as an Administrator and type the cmdlet, Update-Help and it will update all the associated help files.)

Read More

Topics: powershell

PowerShell: Get-Command and Get-Member

Posted by Kris Powell

Sep 11, 2014 9:10:00 AM

kris_resized

Today, I want to show you a couple great cmdlets that can really strengthen your understanding of 

PowerShell: Get-Command and Get-Member.

Get-Command

Get-Command will list all commands that are installed on the computer, including cmdlets, aliases, functions, etc.

Try it out. The results should look something like this:

Get-Commandget-command

There’s a lot of output on the screen, so we can clean this up a little bit to make it easier to read.

Let’s say we just want the name of the commands. We’re going to select only one object property by piping the results of Get-Command and selecting the property that we want to see.

Get-Command | Select-Object Nameget-command select-object name

But, how do we know which object properties exist to select and sort? We’re going to introduce another command today called Get-Member.  

Get-Member

Get-Member tells us about the Properties and Methods of an object.

The easiest way to use it is to pipe in an object that you want to know more about.

Get-Command | Get-Memberget-command get-member

We can see that there are many properties for Get-Command that we can use to sort and view.  Let’s use CommandType and Name.

Get-Command | Select-Object CommandType, Name get-command select-object commandtype name

You should be able to look at that list and find any cmdlet that’s installed that you can use.

In the next blog, we will go over another tool that will help get more detailed information about each cmdlet from within PowerShell itself.

In the meantime, here is more help about Get-Command and Get-Member from Microsoft's Technet:

Get-Command

Get-Member

 
Read More

Topics: powershell

PowerShell:Get-Date Cmdlet

Posted by Kris Powell

Aug 7, 2014 1:26:00 PM

Today, I’d like to make use of an awesome PowerShell cmdlet, Get-Date. Get-Date as the name implies, gets the current date and time and use the results for other cmdlets. Get-Date by itself will return the current date.

powershell get date

We can manipulate this result a handful of ways to make the date into a format that’s more useful to our needs.

We can use -Format to view the date any just about any date format that we can imagine.

powershell get date change format

Here is a great link for which format patterns you can use - http://ss64.com/ps/syntax-dateformats.html

In addition to formatting the date to whatever format suits you best, there are also methods you can use to manipulate the date itself (not just the formatting).

In this example, we can see what day it will be a week from now:

powershell get date manipulate date

Here's a quick list of methods you can use to modify Get-Date:

  • AddDays
  • AddHours
  • AddMilliseconds
  • AddMinutes
  • AddMonths
  • AddSeconds
  • AddTicks
  • AddYears

We can make use of Get-Date and these methods in our scripts to do fancy things like finding all files that have been created within the last 30 days.  We can even take that result and process it to remove the files that are found.

#############################################################################
#   Find files older than 30 days 
#############################################################################

$time = (Get-Date).AddDays(-30)
$path = "C:\temp"

Get-ChildItem -Path $path -Recurse -Force | `
 Where-Object {$_.LastWriteTime -lt $time }

#############################################################################
#   Find files older than 30 days and DELETE
#   Please excercise caution. There is no undo to this action
#############################################################################

$time = (Get-Date).AddDays(-30)
$path = "C:\temp"

Get-ChildItem -Path $path -Recurse -Force | `
 Where-Object {$_.LastWriteTime -lt $time } | `
 Remove-Item -Force -Recurse -ErrorAction SilentlyContinue
Read More

Topics: powershell

Admin Arsenal Blog

Subscribe to Email Updates