Get Lotus Notes calendar entries for a time range in powershell - powershell

I try to track the time I use for projects by adding the project id as a category to a lotus notes calendar entry.
Now I want to select all appointments over a time range (i.e. the last 7 days), group them by category and sum up the time.
Except for the time range thingy it works fine. The solution seams to be the method GetAllDocumentsByKey (https://help.hcltechsw.com/dom_designer/9.0.1/appdev/H_GETALLDOCUMENTSBYKEY_METHOD.html)
I tried to define a time range, a string (subject or category) or an array (values: subject or category) as keyArray but nothing seams to work.
Any idea?
$notesINI = Get-IniContent $env:LOCALAPPDATA\IBM\Notes\Data\notes.ini
$InputNotesMailBox = $notesINI.Notes.MailFile
$InputNotesServer = $notesINI.Notes.MailServer
$DomSession = New-Object -ComObject Lotus.NotesSession
$DomSession.Initialize()
$DomDatabase = $DomSession.GetDatabase($InputNotesServer,$InputNotesMailBox)
$DomView = $DomDatabase.GetView('Calendar')
# This works fine but is really slow because it processes all the documents in my calendar (5Min for 6k documents)
$DomDocRange = $DomView
$DomDoc = $DomDocRange.GetFirstDocument()
$date_s = $(get-date -Year 2022 -Month 4 -Day 7)
$date_e = $(get-date -Year 2022 -Month 4 -Day 14)
while($DomDoc -ne $null){
if($DocCategory -like "proiject-*"){
$Termin_StartDate = $DomDoc.getItemVAlue('StartDateTime')[0]
if(IsBetweenDates2 $date_s $date_e $(get-date $Termin_StartDate)){
# add time and project id to multidimensional array
}
}
}
# does not work because I don't know how to filter getAllDocumentsByKey
$date_s = $(get-date -Year 2022 -Month 4 -Day 7)
$date_e = $(get-date -Year 2022 -Month 4 -Day 14)
$DomDateRange = $DomSession.CreateDateRange()
$DomDateRange.StartDateTime = $DomSession.CreateDateTime($date_s)
$DomDateRange.EndDateTime = $DomSession.CreateDateTime($date_e)
$DomDocRange = $DomView.getAllDocumentsByKey($DomDateRange, $true)
$DomDoc = $DomDocRange.GetFirstDocument()
while($DomDoc -ne $null){
if($DocCategory -like "proiject-*"){
$Termin_StartDate = $DomDoc.getItemVAlue('StartDateTime')[0]
if(IsBetweenDates2 $date_s $date_e $(get-date $Termin_StartDate)){
# add time and project id to multidimensional array
}
}
}

GetDocumentByKey is a function of a view that needs to be sorted by the key you are searching for. The "Calendar"- view is not suitable for this function.
You need to get away from NotesView and get your document collection from the database itself without using the view.
$DomDocRange = $DomDatabase.search( 'Form = "Appointment" & StartDateTime >= [InjectYourStartDateHere] & StartDateTime <= [InjectYourEndDateHere]', Nothing, 0 )
$DomDoc = $DomDocRange.GetFirstDocument()
The constructed #Formula needs to look like this in the end:
Form = "Appointment" & StartDateTime >= [04/01/2022] & StartDateTime <= [04/12/2022]
The brackets are important as they mark the given value as a date. The date needs to be in your local format (MM/DD/YYYY or DD.MM.YYYY or...).
Unfortunately I did not use the interface with Powershell yet, so I can't tell you, how the insert the LotusScript variable "Nothing" here, you could try omit it (use double comma) or use $null...

Related

Finding the Sunday between the 1st and 2nd Tuesday of the month

Fairly new to PS, I want to batch file on Sunday between the 1st and the 2nd Tuesday of the month.
I know how to find the the 1st and 2nd Tuesdays I am looking for, cannot figure out the rest.
$FindNthDay = 1
$WeekDay = 'Tuesday'
[datetime]$Today = [datetime]::NOW
$todayM = $Today.Month.ToString()
$todayY = $Today.Year.ToString()
[datetime]$StrtMonth1 = $todayM + '/1/' + $todayY
while ($StrtMonth1.DayofWeek -ine $WeekDay ) { $StrtMonth1 = $StrtMonth1.AddDays(1) }
$StrtMonth1.AddDays(7 * ($FindNthDay - 1))
#
$FindNthDay = 2
$WeekDay = 'Tuesday'
[datetime]$Today = [datetime]::NOW
$todayM = $Today.Month.ToString()
$todayY = $Today.Year.ToString()
[datetime]$StrtMonth = $todayM + '/1/' + $todayY
while ($StrtMonth.DayofWeek -ine $WeekDay ) { $StrtMonth = $StrtMonth.AddDays(1) }
$StrtMonth.AddDays(7 * ($FindNthDay - 1))
I know how to find the the 1st and 2nd Tuesdays
Since there's only one Sunday in between, you only need to find the first one:
# Get-Date -Day 1 will give us the 1st of the current month
$firstTuesday = Get-Date -Day 1
while($firstTuesday.DayOfWeek -ne 'Tuesday') {
$firstTuesday = $firstTuesday.AddDays(1)
}
And then add another 5 days:
$sundayAfterFirstTuesday = $firstTuesday.AddDays(5).Date
Which (in January 2021) gives us:
PS ~> $sundayAfterFirstTuesday
Sunday, January 10, 2021 12:00:00 AM
In addition to Mathias's fine answer, I got hung up on this. Given that .DayOfWeek is an [enum] that's easily converted to a [Int] I was looking for a mathematically concise way to derive the first Tuesday. Since it's fairly obvious how to then find the following Sunday by just doing .AddDays(5) .
Honestly, I was stumbling a bit because While .DayOfWeek is 0 - 6 how many days to add depends on if the current day, in this case the first of the month, is less than or greater than Tuesday (2). It was worth playing around; here are 2 alternate approaches I came up with:
Example 1: A switch statement that's not at all concise but is very readable:
$Day1 = Get-Date "1/1/2021"
Switch ( $Day1.DayOfWeek )
{
'Sunday' { $Sunday = $Day1.Adddays(2).AddDays( 5 ); Break }
'Monday' { $Sunday = $Day1.Adddays(1).AddDays( 5 ); Break }
'Tuesday' { $Sunday = $Day1.AddDays( 5 ); Break }
'Wednesday' { $Sunday = $Day1.Adddays(6).AddDays( 5 ); Break }
'Thursday' { $Sunday = $Day1.Adddays(5).AddDays( 5 ); Break }
'Friday' { $Sunday = $Day1.Adddays(4).AddDays( 5 ); Break }
'Saturday' { $Sunday = $Day1.Adddays(3).AddDays( 5 ); Break }
}
$Sunday
This is also easy to adjust. For example, if you wanted to switch to 1st Sunday between 1st & 2nd Monday etc...
For the mathematical / logic approach it came out a little more crude:
$Day1 = Get-Date "1/1/2021"
If( [Int]$Day1.DayOfWeek -gt 2 ) { $Interval = 7 - ([Int]$Day1.DayOfWeek - 2) }
Else { $Interval = 2 - [Int]$Day1.DayOfWeek }
$Sunday = $Day1.AddDays( $Interval ).AddDays( 5 )
$Sunday
The above example can be more concise in PowerShell 7+ using the ternary operator:
$Day1 = Get-Date "1/1/2021"
$Interval = $Day1.DayOfWeek -gt 2 ? 7 - ([Int]$Day1.DayOfWeek - 2) : 2 - [Int]$Day1.DayOfWeek
$Sunday = $Day1.AddDays( $Interval ).AddDays( 5 )
$Sunday
Note: all of the examples user 1/1/2021 as the starting date, but I did test across multiple 1st days of the month, For example, if the first day was a Monday, Sunday, Thursday etc...
Note: Some of the [Int] casting can probably be removed if one is careful about PowerShell type conversion system, but I wanted to get this out there. If I have time I'll cleanup further.
Or a slightly different approach:
$BaseDate = (Get-Date 3/1/2021)
$BaseDate.AddDays( (& {if ([int]$BaseDate.DayOfWeek -gt 2) {14}
else { 7 } }) - [int]($BaseDate).DayOfWeek)
Sunday, March 7, 2021 12:00:00 AM

PowerShell Print this business weeks mon-fri

I would like Powershell to determine the current week & print monday - friday in the format:
mm/dd/yyyy - mm/dd/yyyy
I saw a way to get the day of the week which is nice but I would like to just have it show the dates.
What I have so far, it works but if I run any day but Monday the dates would be off:
$bar = "------------------------------------"
$today = (Get-Date)
$dates = #($today.AddDays(0).ToString('MM-dd-yyyy'),
$today.AddDays(1).ToString('MM-dd-yyyy'),
$today.AddDays(2).ToString('MM-dd-yyyy'),
$today.AddDays(3).ToString('MM-dd-yyyy'),
$today.AddDays(4).ToString('MM-dd-yyyy'))
$result = "`n{0}`n{1}`n`n`n{2}`n{3}`n`n`n{4}`n{5}`n`n`n{6}`n{7}`n`n`n{8}`n{9}`n" -f $dates[0], $bar, $dates[1], $bar, $dates[2], $bar, $dates[3], $bar, $dates[4], $bar
echo $result
this seems to do what you want. [grin] it uses the builtin weekday list, indexes into that with the current weekday name, calculates the 1st day of the current week, generates an array of dates for the current week, and finally prints it out with the lines & vertical spacing that you seem to want.
# for my locale, the 1st day is "Sunday"
$WeekDayList = [System.DayOfWeek].GetEnumNames()
$Line = '-' * 40
$Newline = [environment]::NewLine
$BlankLineCount = 3
# the ".Date" property gives you midnite, not "now"
$Today = (Get-Date).Date
$TodayNumber = $WeekDayList.IndexOf($Today.DayOfWeek.ToString())
$WeekStartDate = $Today.AddDays(-$TodayNumber)
$CurrentWeek = foreach ($Offset in 0..6)
{
$WeekStartDate.AddDays($Offset).ToString('yyyy-MM-dd')
}
-join ($CurrentWeek -join "$Newline$Line$($Newline * $BlankLineCount)"), "$Line$($Newline * $BlankLineCount)"
output ...
2019-01-20
----------------------------------------
2019-01-21
----------------------------------------
2019-01-22
----------------------------------------
2019-01-23
----------------------------------------
2019-01-24
----------------------------------------
2019-01-25
----------------------------------------
2019-01-26
----------------------------------------
[not part of the output - needed to show that there are two blank lines above this one. [*grin*]
I have come across the requirement to get a date from a week day, and wrote a function to return a [DateTime].
Using this function and ToString() to format the date to your requirements, gives an output of:
2019/01/21 - 2019/01/25
Code:
Function Get-DateFromDay {
param(
[Parameter(Mandatory = $true)]
[ValidateSet('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday')]
[string]$WeekDay,
[Int]$AddWeeks = 0
)
$DayNumber = #{
'Saturday' = 1;
'Sunday' = 0;
'Monday' = -1;
'Tuesday' = -2;
'Wednesday' = -3;
'Thursday' = -4
'Friday' = -5
}
[System.Datetime]$Today = Get-Date
$NumDaysSinceDateFromDay = $Today.DayOfWeek.value__ + $DayNumber[$WeekDay]
[System.Datetime]$DateFromDayThisWeek = $Today.AddDays(-$NumDaysSinceDateFromDay)
$DateFromDayThisWeek.AddDays( + ($AddWeeks * 7))
}
$Monday = (Get-DateFromDay -WeekDay Monday).ToString('yyyy/MM/dd')
$Friday = (Get-DateFromDay -WeekDay Friday).ToString('yyyy/MM/dd')
Write-Output "$Monday - $Friday"
And a few examples of use for those who come across this post in the future:
Thursday next week:
Get-DateFromDay -WeekDay Thursday -AddWeeks 1
Tuesday last week:
Get-DateFromDay -WeekDay Tuesday -AddWeeks -1

Powershell script assign food to numbers and list them

The script should allocate and list the numbers of the particular foods.
So i want a Script that makes a "Plan" of the Food i'm gonna eat this week.
i have a counter that can "choose from 200 meals".
So what i need is that it is like this:
number* = Tacos
number* = Pizza
...continuing like this
I don't have a clue how to do this... i hope you can help me!
here is my code untill now.
# Food selector for the week!
#random Stuff mixed for every day.
function Random-Food{
Param(
[array]$InputList
)
return $InputList | Get-Random -Count 7
$InputList.Count;
}
$a = 1..200
Write-Output (Random-Food -InputList $a)
In a separate file, create an enumeration (for readability):
Enum Food
{
Tacos
Pizza
...
}
In your script, dot-source this file so you have it available: . 'C:\myenum.ps1'
Then in your function:
function Get-Food {
[Enum]::GetValues([Food]) | Get-Random -Count 7
}
This will return 7 random foods from your list. As an added bonus, you can assign a number to each food and get that reference as well. (Tacos = 5 and access it like [Food]::Tacos which can be treated as a string or integer)
To include the day:
function Get-Food {
$foodsOfWeek = [Enum]::GetValues([Food]) | Get-Random -Count 7
foreach ($day in [Enum]::GetValues([DayOfWeek])) {
([string]$day).Substring(0, 3) + ': ' + $foodsOfWeek[$day]
}
}
An explanation:
The function will grab all the values (Tacos, Pizza, etc.) from your custom [Food] enumeration and then randomly select 7 of those to put into an array that we store into $foodsOfWeek.
At that point, we need to loop through the days of the week (system built-in enumeration [DayOfWeek]). We type-cast to a string so we can call the .Substring() method to grab the first 3 characters and append a : for formatting.
Finally, we access the $foodOfWeek array using the [DayOfWeek] enumeration since days correlate to the numbers 0-6 (the size of our array).
(DayOfWeek.Sunday == 0) && (DayOfWeek.Sunday == "Sunday")) == true
To learn PowerShell, try this: Windows PowerShell 3.0 Step by Step - Pearsoncmg.com
Freebie follows. Written and tested on A Win 7 machine with PowerShell 4. I included a few foods. All you have to do is add items to the $foodList.
Sample output follows the code
cls
#define an array of strings and load it with food words
$foodList = #("Apples","Bananas", "Cherries","Grapes","Mangoes","Melons","Oranges","Peaches","Pears","Pineapples","Strawberries","Tomatoes")
#define an array of days
$dow = #("Mon","Tue","Wed","Thu","Fri","Sat","Sun")
#loop 7 times, once per day and generate a random number between 0 and the number of food items - 1
for ($i = 0; $i -lt 7; $i++)
{
$foodItemIndex = Get-Random -Minimum 0 -Maximum ($foodList.Count - 1)
write-host ($dow[$i] + ": " + $foodList[$foodItemIndex])
}
Here's one way to do it:
$foodChoices = "Pizza","Taco","Dim Sum","Burger","Salad","Soup","Sandwich","Curry"
$foodChoices[(Get-Random -InputObject (0..($foodChoices.Count - 1)) -Count 7)] |
ForEach-Object {$daysOfWeek = [enum]::GetNames([DayOfWeek]); $day=0}{
[PsCustomObject]#{
Day=$daysOfWeek[$day++]
Food=$_
}
}
Output will look something like this:
Day Food
--- ----
Sunday Burger
Monday Sandwich
Tuesday Salad
Wednesday Taco
Thursday Soup
Friday Dim Sum
Saturday Curry
Just add more items to $foodChoices and you're good to go ...

Get the number of Days in the current month using powershell

I have the need to retrieve the number of days in the current month, and despite my research, I have yet to find anything in powershell that does it. The following is what I have currently built to get the result I want. is there a better way to do it?
Please note that I am limited to Powershell
#check to see if this is a leap year
function LYC
{
if ([System.DateTime]::isleapyear((Get-Date).Year))
{
$Global:LY = True
}
}
#Get the number of days in current month
function fNOD
{
$MNum = (Get-Date).Month
switch ($MNum)
{
1 {$Global:DaysInMonth=31}
2 {
LYC
if (LY)
{
$Global:DaysInMonth=29
} else {
$Global:DaysInMonth=28
}
}
3 {$Global:DaysInMonth=31}
4 {$Global:DaysInMonth=30}
5 {$Global:DaysInMonth=31}
6 {$Global:DaysInMonth=30}
7 {$Global:DaysInMonth=31}
8 {$Global:DaysInMonth=31}
9 {$Global:DaysInMonth=30}
10 {$Global:DaysInMonth=31}
11 {$Global:DaysInMonth=30}
12 {$Global:DaysInMonth=31}
}
}
http://msdn.microsoft.com/en-us/library/system.datetime.daysinmonth.aspx
# static int DaysInMonth(int year, int month)
[DateTime]::DaysInMonth(2013, 3)
Assuming you want it for any date stored in $date:
((get-date $date -Day 1 -hour 0 -Minute 0 -Second 0).AddMonths(1).AddSeconds(-1)).Day
This seems to me like it might be deceptively easy:
$numDays = ((Get-Date -Month 3) - (Get-Date -Month 2))
28 days in February, July minus June gives me 30 days.
As mentioned below, that apparently sometimes does some weird integer rounding that gives off 29d, 23h, 59m or something else not right.
This seems to be consistent:
$monthLess = Get-Date -Month 4
$NumDays = (Get-Date -Month 5).Subtract($monthLess)

Operation with dates with format ISO 8601?

I need to make an PHP operation with dates with format ISO 8601. Something like:
$starDate = 2012-03-20T00:00:00+01:00; //20 March 2012
$endDate = 2012-04-01T00:00:00+02:00; // 1 April 2012
$diff = $starDate - $endDate; //Result should be: 13
Using this code $diff get a value of cero.
Try this :
function date_diff($date1, $date2)
{
$s = strtotime($date2)-strtotime($date1);
$d = intval($s/86400)+1;
return "$d";
}
Source : http://forum.hardware.fr/hfr/Programmation/PHP/php-calculer-nombre-sujet_30415_1.htm