Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate month-folders and day-subfolders for a whole year

Tags:

powershell

I created a script which generates in a given path (first parameter) folders for each month (format yyyy_mm) and in each of those folders subfolders for each day (format yyyy_mm_dd).

The code works, but is there any easier solution?

param(
[string]$inppath = '',
[string]$inpyear = '0'
)
function dayfolder
{
  1..[DateTime]::DaysInMonth($inpyear,$month) | ForEach-Object { 
    $day = $_
    New-Item -ItemType directory -Force -Path ($inppath + '\' + $inpyear + '_' + ("{0:D2}" -f $month) + '\' + $inpyear + '_' + ("{0:D2}" -f $month) + '_' + ("{0:D2}" -f $day) ) }
}

if ($inppath -eq '')
{
    echo 'No path in input! First parameter!'
}
else
{
    if ($inpyear -eq '0')
    {
      echo 'No year in input! Second parameter! Format: YYYY'
    }
    else
    {
    1..12 | ForEach-Object { 
            $month = $_
            New-Item -ItemType directory -Force -Path ($inppath + '\' + $inpyear + '_' + ("{0:D2}" -f $month))
            dayfolder
            }
    }       
}
like image 807
Esteban P. Avatar asked Dec 16 '14 08:12

Esteban P.


People also ask

How do I make multiple folders in command prompt?

Creating multiple folders is easier from the command line. You can type mkdir followed by the names of each folder, separated by a space to do this. Note: Alternately, you can use the md command in place of mkdir. They do the same thing.


1 Answers

I think you are making things overly complicated by providing defaults for your arguments and then giving error messages when the defaults are used. If you want the parameters to be mandatory you should declare them as such. In fact you can go further and declare them as being a valid path and a number in a particular range.

Otherwise my main observation would be that New-Item creates any parent items that it needs, so you don't need to create the month folders separately.

There are various ways to build up the path string, but I think in this case it is simplest to format the month and day and then just use a single string (note that as _ is a valid character in a variable name you have to use the ${...} form of variable expansion in some cases):

param(
    # Path to an existing folder.
    [Parameter(Mandatory=$True)]
    [ValidateScript({Test-Path $_ -PathType 'Container'})] 
    [string]$inppath,

    # Year must be fairly recent or in the future. Warranty expires 2100
    [Parameter(Mandatory=$True)]
    [ValidateRange(1999,2100)]
    [int]$inpyear
)

1..12 | ForEach-Object {
    $month = "{0:D2}" -f $_
    1..[DateTime]::DaysInMonth($inpyear,$month) | ForEach-Object { 
       $day = "{0:D2}" -f $_
        New-Item -ItemType directory -Force -Path "$inppath\${inpyear}_$month\${inpyear}_${month}_${day}"
    }
}

The only other thing is that if you want to use this often, it would be better to turn it into a function or cmdlet and then you can keep it in a module with other cmdlets. Also if you do that the comment before each parameter becomes part of the help screen and you can include a description and examples for the help screen in a comment at the top of the function declaration.

P.S. For bloody powershell beginners I recommend http://www.microsoftvirtualacademy.com/training-courses/getting-started-with-powershell-3-0-jump-start

like image 64
Duncan Avatar answered Sep 30 '22 12:09

Duncan