How to create and verify folders and sub-folders based on a calendar year ?

I wonder How to create and verify folders and sub-folders based on a calendar year ?
For example, year 200
Script will do:
1. Create folder YYYY
1.1. Create subfolder 1 (Month 1 or January)
1.1.1 Create subfolder 1 (Day 1) under the folder 1 (month 1)
1.1.2 Create subfolder 2 (Day 2) under the folder 1 (month 1)
1.1.3 Verify if subfolder for the day exist, if not Create subfolder for the day in this case 3 (Day 3) under the folder 1 (month 1)
1.1.y And so on until the last day of the month 1
1.2 Create subfolder 2 (Month 2 or February)
1.2.1 Create subfolder 1 (Day 1) under the folder 1 (month 2)
1.2.2 Create subfolder 2 (Day 2) under the folder 1 (month 2)
1.2.3 Verify if subfolder for the day exist, if not Create subfolder for the day in this case 3 (Day 3) under the folder 2 (month 2)
1.2.y And so on until the last day of the month 2
1.x. Create subfolder n (until the last month of the year
1.x.y Create subfolder y (Day y) under the folder x (month x).
2. Create folder for the next year and Verify Year
And continue the creation of subfolders about the months and respective days

Do you understand ?

Thanks for your help
namergSystems AdministratorAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

David Johnson, CD, MVPOwnerCommented:
function New-Basepath
{
  <#
    .SYNOPSIS
    Short Description
    .DESCRIPTION
    Detailed Description
    .EXAMPLE
    New-basepath
    explains how to use the command
    can be multiple lines
    .EXAMPLE
    New-basepath
    another example
    can have as many examples as you like
  #>
  param
  (
    [Parameter(Position=0)]
    [string] $basedir = "$env:HOMEDRIVE\Test",
    [Parameter(Position=1)] [int] $month = 1,
    [Parameter(Position=2)][int]$days = 0,
    [Parameter(Position=3)][int]$day = 0,
    [Parameter(Position=4)][int]$year = 200
  )
  
  for ($month -eq 1; $month -le 12; $month++){
    switch($month){
      9 { $days = 30}  # September
      4 { $days = 30}  # April
      6 { $days = 30}  # June
      11 { $days = 30} # November
      2  { 
        if (($year %4) -eq 0) {  #using mod operator
          $days = 29
        }
        else {$days = 28}
      }
      default { $days = 31}
    }
    for ($day = 1; $day -le $days; $day++)
    {
      #     write-output -InputObject $basedir, $year, $days, $day, $month
      $newpath = $basedir + '\' + $year + '\'+$month + '\' + $day
      
      if (!(test-path -Path $newpath)) {
        write-output (('{0} does not exist creating new directory' -f $newpath))
        mkdir -Path $newpath 
        if (!(test-path -Path $newpath)) {
          write-output(('Error creating {0} ' -f $basedir))
          break;
        }
        else {
          write-output (('{0} created' -f $newpath))
        }
      }
    }
  }
}

Open in new window

0
namergSystems AdministratorAuthor Commented:
Hmm, will that script covers the 29 vs 28 days of February. Every three years Feb has 29 days.
0
David Johnson, CD, MVPOwnerCommented:
yes and I edited to add the year  that was missing
0
Simplify Active Directory Administration

Administration of Active Directory does not have to be hard.  Too often what should be a simple task is made more difficult than it needs to be.The solution?  Hyena from SystemTools Software.  With ease-of-use as well as powerful importing and bulk updating capabilities.

namergSystems AdministratorAuthor Commented:
Can you tell me how would i run the script ?
0
namergSystems AdministratorAuthor Commented:
I do not think the user would like to enter parameters at all.
0
namergSystems AdministratorAuthor Commented:
What if you create something static but yes beginning in year 200.

I started doing this but i will end up with lot of for and ifs.

#Year2000
$FolderPath = "C:\Scripts\FolderPath\"
$Year2000 = 2000; $DaysMonth1 = 31; $DaysMonth2 = 29; $DaysMonth3 = 31; $DaysMonth4 = 30; $DaysMonth5 = 31; $DaysMonth6 = 30; $DayMonth7 = 31; $DaysMonth8 = 31; $DaysMonth9 = 30; $DaysMonth10 = 31; $DaysMonth11 = 30; $DaysMonth12 = 31
$Year2001 = 2001; $Year2001Month2 = 28
$Year2002 = 2002; $Year2002Month2 = 28
$Year2003 = 2003; $Year2003Month2 = 28
$Year2004 = 2004; $Year2004Month2 = 29
$Year2005 = 2005; $Year2005Month2 = 28
$Year2006 = 2006; $Year2006Month2 = 28
$Year2007 = 2007; $Year2007Month2 = 28
$Year2008 = 2008; $Year2008Month2 = 29
$Year2009 = 2009; $Year2009Month2 = 28
$Year2010 = 2010; $Year2010Month2 = 28
$Year2011 = 2011; $Year2011Month2 = 28
$Year2012 = 2012; $Year2012Month2 = 29
$Year2013 = 2013; $Year2013Month2 = 28
$Year2014 = 2014; $Year2014Month2 = 28
$Year2015 = 2015; $Year2015Month2 = 28
$Year2016 = 2016; $Year2016Month2 = 29
$Year2017 = 2017; $Year2017Month2 = 28
$Year2018 = 2018; $Year2018Month2 = 28


If (test-path  "C:\Scripts\FolderPath\$Year2000") {
Write-host "Folder 2000 does exist"
	If (test-path "C:\Scripts\FolderPath\$Year2000\") {
	
		Write-host "Folder 1 for Month 1 does exist"
	}
}
Else { Write-host "Folder 2000 does NOT exist" }

Open in new window

0
David Johnson, CD, MVPOwnerCommented:
it is a function
so you can load it via .\filename.ps1 and then 'new-basepath'  or strip out
function new-basepath 
{

Open in new window

and the ending
}

Open in new window

and save it as a script.ps1 file then you can run
.\script.ps1 -year 2018 -basedir x:\base

get-help .\script.ps1 will show you the command line options available.
0
David Johnson, CD, MVPOwnerCommented:
 2  { 
        if (($year %4) -eq 0) {  #using mod operator if year divisible by 4 leaves no remainder then 
          $days = 29
        }
        else {$days = 28}

Open in new window

0
namergSystems AdministratorAuthor Commented:
Hmm, i got lost... I understood this part: \script.ps1 -year 2018 -basedir x:\base and what about this:

 { 
        if (($year %4) -eq 0) {  #using mod operator if year divisible by 4 leaves no remainder then 
          $days = 29
        }
        else {$days = 28}

Open in new window

0
namergSystems AdministratorAuthor Commented:
I did execute the following .\CreateVerifyCalendar.ps1 -Year 2000 -basedir C:\Scripts\FolderPath but did not do anything
0
footechCommented:
Here's an alternative.
$year = Read-Host "Enter year"
$basePath = "C:\temp"
1..((Get-Date "12/31/$year").DayOfYear) | ForEach { ([datetime]"01/01/$year").AddDays($_ - 1).ToString("yyyy\\MM\\dd") } | ForEach `
{
    New-Item -Path (Join-Path $basePath $_) -ItemType Directory | Out-Null
}

Open in new window

0
namergSystems AdministratorAuthor Commented:
@footech not quite, see screenshot
Screenshot_1.png
0
footechCommented:
What's missing?
There's a folder for the year, under that a folder for each month, and under each month a folder for each day.
folders
0
footechCommented:
BTW, I just tested David's code and it did pretty much the same.  One difference is that mine has leading 0's for single-digit days and months, but that's easily changed.
0
namergSystems AdministratorAuthor Commented:
@footech hmm about your code very odd it only created 2000\12\31 and not the other subfolders
0
namergSystems AdministratorAuthor Commented:
@david when i do the following i do not get any help
PS C:\Scripts> get-help .\CreateVerifyCalendar.ps1
CreateVerifyCalendar.ps1

Open in new window

0
footechCommented:
I can't recreate the issue you mentioned.
What version are you running?  Start a new powershell session to test.
0
namergSystems AdministratorAuthor Commented:
PS C:\Scripts> $PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
5      0      10586  117
0
namergSystems AdministratorAuthor Commented:
Now, i installed the latest:
PS G:\> $PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      14409  1005

And i get the following error:

PS G:\> ((Get-Date "12/31/$year").DayOfYear) | ForEach { ([datetime]"1/1/$year").AddDays($_ - 1).ToString("yyyy\\MM\\dd") } | ForEach {New-Item -Path (Join
-Path $basePath $_) -ItemType Directory | Out-Null}
Get-Date : Cannot bind parameter 'Date'. Cannot convert value "12/31/" to type "System.DateTime". Error: "String was not recognized as a valid DateTime."
At line:1 char:12
+ ((Get-Date "12/31/$year").DayOfYear) | ForEach { ([datetime]"1/1/$yea ...
+            ~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-Date], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.GetDateCommand

Open in new window

0
footechCommented:
Only way to get that is to not run the first line
$year = Read-Host "Enter year"
or enter a blank.
0
David Johnson, CD, MVPOwnerCommented:
#requires -Version 2.0
<#
    .SYNOPSIS
    Short Description
    .DESCRIPTION
    Detailed Description
    .EXAMPLE
    New-basepath
    explains how to use the command
    can be multiple lines
    .EXAMPLE
    New-basepath
    another example
    can have as many examples as you like
#>
param
(
  [Parameter(Position = 0)]
  [string] $basedir = "$env:HOMEDRIVE\Test",
  [Parameter(Position = 1)] [int] $month = 1,
  [Parameter(Position = 2)][int]$days = 0,
  [Parameter(Position = 3)][int]$day = 0,
  [Parameter(Position = 4)][int]$year = 200
)
  
for ($month -eq 1; $month -le 12; $month++)
{
  switch($month){
    9 
    {
      $days = 30
    }  # September
    4 
    {
      $days = 30
    }  # April
    6 
    {
      $days = 30
    }  # June
    11 
    {
      $days = 30
    } # November
    2  
    { 
      if (($year %4) -eq 0) 
      {
        #using mod operator
        $days = 29
      }
      else 
      {
        $days = 28
      }
    }
    default 
    {
      $days = 31
    }
  }
  for ($day = 1; $day -le $days; $day++)
  {
    $smonth = $month.tostring('00')
    $sday = $day.tostring('00')
    #     write-output -InputObject $basedir, $year, $days, $day, $month
    $newpath = $basedir + '\' + $year + '\'+$smonth + '\' + $sday
      
    if (!(Test-Path -Path $newpath)) 
    {
      Write-Verbose -Message (('{0} does not exist creating new directory' -f $newpath))
      $null = mkdir -Path $newpath
      if (!(Test-Path -Path $newpath)) 
      {
        Write-Output -InputObject (('Error creating {0} ' -f $basedir))
        break
      }
      else 
      {
        Write-Verbose -Message ('{0} created' -f $newpath)
      }
    }
  }
}
#  }

Open in new window

Added leading 0
Video: https://www.screencast.com/t/FMvT08j8K
0
Sajen JoseCommented:
I guess another way of achieving the result would be:

Clear-Host
# Enter the  appropriate year here
$Year = 2018
$MonthList = @("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12") 


New-Item -ItemType Directory -Path C:\temp\$Year 

foreach ($monthnum in $MonthList)
{
    $month = (Get-Culture).DateTimeFormat.GetMonthName($monthnum)
    New-Item -ItemType Directory -Path C:\Temp\$Year\$month
    $MonthDays = [datetime]::DaysInMonth($Year, $monthnum)
    for ($i = 1; $i -le $MonthDays; $i++)
    {
        New-Item -ItemType Directory -Path C:\Temp\$Year\$month\$i;
    }

}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Sajen JoseCommented:
Added the validation check "If Folder exists". You will need to update the value for the $Year and also the path to reflect your choice, currently I have used a random path like C:\Temp, you can use a variable for that as welll

Clear-Host
#Change Value here... 
$Year = 2018
$MonthList = @("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12") 

If ((Test-Path C:\temp\$Year) -eq $False)
{
    New-Item -ItemType Directory -Path C:\temp\$Year 

}


foreach ($monthnum in $MonthList)
{
    $month = (Get-Culture).DateTimeFormat.GetMonthName($monthnum)
    
    If((Test-Path C:\Temp\$Year\$month) -eq $False)
    {
        New-Item -ItemType Directory -Path C:\Temp\$Year\$month
    }
    $MonthDays = [datetime]::DaysInMonth($Year, $monthnum)
    for ($i = 1; $i -le $MonthDays; $i++)
    {
        IF((test-path C:\Temp\$Year\$month\$i) -eq $False)
        {
            New-Item -ItemType Directory -Path C:\Temp\$Year\$month\$i;
        }
    }

}

Open in new window

0
namergSystems AdministratorAuthor Commented:
@SajeJose almost, almost but what if instead of writing out the name of the months, just the number of the month: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 as subfolders ? See attachment
Screenshot_2.png
0
namergSystems AdministratorAuthor Commented:
I think i got it.

Clear-Host
#Change Value here... 
$year = Read-Host "Enter year"
#$Year = 2000
$MonthList = @("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12") 

If ((Test-Path C:\Scripts\FolderPath\$Year) -eq $False)
{
    New-Item -ItemType Directory -Path C:\Scripts\FolderPath\$Year 

}


foreach ($monthnum in $MonthList)
{
    $monthnum
	$month = (Get-Culture).DateTimeFormat.GetMonthName($monthnum)
    
	If ((Test-Path C:\Scripts\FolderPath\$Year\$monthnum) -eq $False)
    {
		New-Item -ItemType Directory -Path C:\Scripts\FolderPath\$Year\$monthnum
    }
    $MonthDays = [datetime]::DaysInMonth($Year, $monthnum)
    for ($i = 1; $i -le $MonthDays; $i++)
    {
		if ((test-path C:\Scripts\FolderPath\$Year\$monthnum\$i) -eq $False)
        {
			New-Item -ItemType Directory -Path C:\Scripts\FolderPath\$Year\$monthnum\$i;
		}
    }

}

Open in new window

0
footechCommented:
Whatever works for you.  There's some pieces in that that aren't really needed, but I won't quibble over them.
I only posted mine to show that it could be done with much fewer lines of code (always better to use datetime methods and properties than trying to build your own logic, in my opinion).  FWIW, I tested on a couple different machines with different OSes and never ran into a problem.  I have to assume the problem's on your end.

If you have no further questions regarding this, please go ahead and close the question.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.