Comparing PowerShell / SharePoint list dates - powershell

I am trying to use PowerShell to get the dates from a Sharepoint list and compare today's date to see if there is a match.
I have some code so far but it doesn't seem to be working. I am guessing I have some data types wrong when I am doing a comparison or something of that nature. This is the code I have so far below:
$unusableDatesArray is set with a CAML query to a list in SharePoint
The column name of the date field in SharePoint is called 'UnusableDate' and of type date/time
$todaysDate = Get-Date
$foundUnusableDate = $false
ForEach($item in $unusableDatesArray) {
if($item['UnusableDate'] -eq $todaysDate) {
$foundUnusableDate = $true
}
}
Even though both values appear to have 8/10/2017 12:00:00 AM as the value when I find a matching date, $foundUnusableDate never ends up being true. If anyone knows what I am doing wrong please chime in.

-eq is a "hard" comparison operator to get a $true out of it, both variables would need to be at the exact same datetime. This would return $true:
$date1 = [datetime]'8/11/2017 12:00:00'
$date2 = [datetime]'8/11/2017 12:00:00'
if ($date1 -eq $date2) {$true
} else {$false}
while a simple difference of one second would cause it to return $false
$date1 = [datetime]'8/11/2017 12:00:00'
$date2 = [datetime]'8/11/2017 12:00:01'
if ($date1 -eq $date2) {$true} else {$false}
To work around that you can use different approaches
$date1 = [datetime]'8/11/2017 12:00:00'
$date2 = Get-Date
if (('{0:yyyyMMdd}' -f $date1) -eq ('{0:yyyyMMdd}' -f $date2)) {$true} else {$false}
if ($date1.Date -eq $date2.Date) {$true
} else {$false}
$date1 = ([datetime]'8/11/2017 12:00:00').Date
$date2 = (Get-Date).Date
if ($date1 -eq $date2) {$true} else {$false}

$dateToCheck = Get-Date
ForEach($item in $unusableDatesArray) {
[DateTime]$sharePointDate = $item['UnusableDate']
if(Get-Date $sharePointDate -Format 'MM/dd/yyyy') -eq (Get-Date $dateToCheck -Format 'MM/dd/yyyy')) {
$foundUnusableDate = true
}
}
The above is my final solution

Related

powershell IF condition in a Variable

I've been strugling on a little thing for few hours now, and I wanted to know if one of you have the solution (maybe i'm missing a little thing)
I got a switch for setting the condition in a IF but seems it doesn't interprete it as a if condiction
switch ( $CampaignStatus )
{
"Complete" { $CampainCondition = ($DateStr -eq (get-date -Format "MM/dd/yyyy")) }
"Incomplete" { $CampainCondition = ($DateStr -eq (get-date -Format "MM/dd/yyyy")) }
"InProgress" { $CampainCondition = ($DateStr -gt (get-date -Format "MM/dd/yyyy")) }
}
foreach($c in $CampaignList) {
$index = $index +1
$DateStr = ConvertToFriendlyDate -Date $c.deadline
if ($CampainCondition) { blablabla}
Any idea ?
I tried with quotes, without etc
You're looking for Script Blocks to store those expressions and later evaluate them:
$CampainCondition = switch ( $CampaignStatus ) {
"Complete" { { $DateStr -eq (Get-Date -Format "MM/dd/yyyy") } }
"Incomplete" { { $DateStr -eq (Get-Date -Format "MM/dd/yyyy") } }
"InProgress" { { $DateStr -gt (Get-Date -Format "MM/dd/yyyy") } }
}
Then for evaluation, you can use the call operator &:
foreach($c in $CampaignList) {
$index = $index++
$DateStr = ConvertToFriendlyDate -Date $c.deadline
if(& $CampainCondition) {
<# blablabla #>
}
<# blablabla #>
}
As for the conditions themselves, instead of converting the date into a specific format (Get-Date -Format "MM/dd/yyyy") and then comparing that string with $DateStr, it would a much better idea to parse $DateStr as a DateTime instance and compare that against today's date.

How to do time "HH:mm" comparison in Powershell?

Apparently my code is like this and it is now working. I think the logic is already there. the $openTime and $closeTime is read from csv using import-csv in "HH:mm" form.
$openTime = $ip.openTime
$closeTime = $ip.closeTime
$time = Get-Date -UFormat "%R"
if (($time -ge $openTime) -and ($time -le $closeTime)) {
Write-Host "Store is Open!" -ForegroundColor Green
}else{
Write-Host "Store is outside open hours!" -ForegroundColor Red
}
powershell 7
$csv = #"
store, openTime, closeTime
Wallmart, 08:00, 18:00
Ikea, 10:00, 20:30
"# | ConvertFrom-Csv
Get-Date
$csv | ForEach-Object{
[int]([datetime]::Now - [datetime]::Today).TotalMinutes -in (.{[int]$args[0][0]*60 + [int]$args[0][1]} $_.openTime.split(":"))..(.{[int]$args[0][0]*60 + [int]$args[0][1]} $_.closeTime.split(":")) ? "Store {0} is Open! " -f $_.store : "Store {0} is outside open hours!" -f $_.store
}
16 февраля 2021 г. 8:52:42
Store Wallmart is Open!
Store Ikea is outside open hours!
powershell 5
$csv = #"
store, openTime, closeTime
Wallmart, 08:00, 18:00
Ikea, 10:00, 20:30
"# | ConvertFrom-Csv
Get-Date
$csv | ForEach-Object{
("Store {0} is outside open hours!", "Store {0} is Open! ")[[int]([datetime]::Now - [datetime]::Today).TotalMinutes -in (.{[int]$args[0][0]*60 + [int]$args[0][1]} $_.openTime.split(":"))..(.{[int]$args[0][0]*60 + [int]$args[0][1]} $_.closeTime.split(":"))] -f $_.store
}
Try it online!
I find it's much easier to work with date and times if I convert them to [DateTime] objects. We can use the DateTime class method ParseExact to convert the time into [DateTime] objects for us. This object will actually contain today's date as well as the time we supply, but for our purposes this is fine since the $time object also will be today's date. For the current time ($time) just let Get-Date return to us a [DateTime] object that will represent the current date and time (now). After that the rest of your code works as expected. Hurray!
# this $ip hashtable object just represents data similar to your csv import
$ip = #{
openTime = "09:00"
closeTime = "21:00"
}
$openTime = [datetime]::ParseExact($ip.openTime, 'HH:mm', $null)
$closeTime = [datetime]::ParseExact($ip.closeTime, 'HH:mm', $null)
$time = Get-Date
if (($time -ge $openTime) -and ($time -le $closeTime)) {
Write-Host "Store is Open!" -ForegroundColor Green
}
else {
Write-Host "Store is outside open hours!" -ForegroundColor Red
}
If you are working with the time are imported from csv, make sure the time format in the csv file is in "HH:mm"

Update SharePoint list field using powershell based on Date comparison

I am currently try to update SharePoint field (Dropdown field called Overdue to Yes if the dateFormat field is equal or less than current date. At this stage, it does not change the value. Is there anything that i missed. Please refer the code i have below. Thanks
if((Get-PSSnapin | Where {$_.Name -eq "Microsoft.SharePoint.PowerShell"}) -eq $null) {
Add-PSSnapin Microsoft.SharePoint.PowerShell;
}
$SPWeb = Get-SPWeb "http://contoso/sites/test";
$List = $SPWeb.Lists["Catalog"];
$currentDate = Get-Date (Get-Date) -format dd/MM/yyyy;
$items = $List.Items;
foreach ($item in $items) {
$deadline = $item["TA Deadline"];
$dateFormat = Get-Date $deadline -format dd/MM/yyyy;
#if date Format is less or equal than current date then update the Overdue drop down field to yes
if($dateFormat -le $currentDate)
{
$item["Overdue"] = "YES"
$item.Update()
}
}
$SPWeb.Dispose();
I think you need to supply an index/numerical numerical value for the choice. See the blog post here.
As it mentions you could do:
$item["Overdue"] = 0; #assuming 0 == YES
Or
$item["Overdue"] = $list.Fields["Overdue"].GetFieldValue("YES");
New code for the datetime logic
if((Get-PSSnapin | Where {$_.Name -eq "Microsoft.SharePoint.PowerShell"}) -eq $null) {
Add-PSSnapin Microsoft.SharePoint.PowerShell;
}
$SPWeb = Get-SPWeb "http://contoso/sites/test";
$List = $SPWeb.Lists["Catalog"];
$currentDate = Get-Date;
$items = $List.Items;
foreach ($item in $items) {
$deadline = $item["TA Deadline"];
$dateFormat = [datetime]$deadline
#if date Format is less or equal than current date then update the Overdue drop down field to yes
if($dateFormat -le $currentDate)
{
$item["Overdue"] = "YES"
Write-Debug $item["Overdue"]
$item.Update()
}
}
$SPWeb.Dispose();
if the Overdue column is a yes/no field (Boolean) I guess You can either do like Dana V suggested, so:
$item["Overdue"] = 0
or
$item["Overdue"] = $true

Powershell compare months and exclude which are not required

I have a text file as shown below. I need to preserve the files which are within 6 months old (from the previous month) and write every other content to other file which are more than 6 months old.
What I've done so far is like:
$array3 =
do {
foreach($monthl in $monthlookup)
{
$mnthl = $monthl -split '-'
$m_day = $mnthl[1]
$m_month = $mnthl[2]
$m_year = $mnthl[3]
$m_temp = 0
$prevmonth = (Get-Date).AddMonths(-1).ToString("dd-MM-yy")
while(($m_temp -eq "0"))
{
if(($m_month -ge $startmonth) -and ($m_month -le $prevmonth))
{
$monthl | Add-Content "C:\each_month_latest.txt"
break;
}else
{
$monthl | Add-Content "C:\exclusions.txt"
}
}
}
} until ($m_month -ge $m)
What the issue I identified here is like: If the current month is 1, then it wont go back to the last 6 months and check, as I use just strings here.
Any suggestions or code improvements, anyone of you can think of..? Would be really appreciated.
Edit
monthlookup will look like:
testdatabase-30-11-14-23-00
testdatabase-31-12-14-23-00
testdatabase-30-01-15-23-00
testdatabase-31-01-15-23-00
testdatabase-27-05-15-23-00
testdatabase-28-02-15-23-00
testdatabase-31-03-15-23-00
testdatabase-30-04-15-23-00
testdatabase-31-05-15-23-00
$m is $m = Get-Date -Format "MM"
Well, I don't completly understand what you want to do but here some tipps:
$prevmonth = (Get-Date).AddMonths(-1).ToString("dd-MM-yy") shouldn't be done each time within the foreach loop
You could extract the date using a simple regex: [regex]::Match('testdatabase-30-11-14-23-00', '^.*?-(\d{2}-\d{2}-\d{2}-\d{2}-\d{2}$)').Groups[1].Value
Parse the date using [datetime]::ParseExact and a format string
So it could look like this:
# this doesn't have to be done each time in the foreach loop
$sixMonthBefore = (Get-Date).AddMonths(-6)
foreach($monthl in $monthlookup)
{
# extract the date
$dateString = [regex]::Match($monthl, '^.*?-(\d{2}-\d{2}-\d{2}-\d{2}-\d{2}$)').Groups[1].Value
# create a datetime using format string
$date = [datetime]::ParseExact($dateString, 'dd-MM-yy-HH-mm', $null)
if ($date.Month -eq (Get-Date).Month -and $date.Year -eq (Get-Date).Year)
{
Write-Host "$monthl is from this month"
}
elseif ($date -gt $sixMonthBefore)
{
$monthl | Add-Content "C:\each_month_latest.txt"
}
else
{
$monthl | Add-Content "C:\exclusions.txt"
}
}

filtering and though a sharepoint list items with powershell

I have tried below but not getting any result back
Not sure if i'm doing this well.
Can i filter in the foreach or in my if statement
Thanks in advance
[DateTime] $CreatedDate = $item["Created"]
$convertedCreatedDate = $CreatedDate.ToString("yyyy-MM-dd")
$today = (Get-Date).AddDays(-1).ToString("yyyy-MM-dd")
foreach ($item in $list.items | where {$convertedCreatedDate -eq $today}) {
if ($list.items | where {$convertedCreatedDate -eq $today})
{
Write-Host $item["Created"]
}
Write-Host $item["Created"]
}
You can use a complex expression in your foreach as you're doing above. I would wrap it in a #() to make the code a bit more readable and to ensure the result is an array (either length 0, 1 or n) e.g.:
foreach ($item in #($list.items | where {$convertedCreatedDate -eq $today})) {
You can also simplify you're date testing by using the Date property on a DateTime e.g.:
$convertedCreatedDate = ([DateTime]$item["Created"]).Date
$today = (Get-Date).Date
You can also put a complex expression within an if statement condition but PowerShell will only evaluate whether the statement is $true or $false. PowerShell does lots of coercion to try to take something like:
$list.items | where {$convertedCreatedDate -eq $today}
And convert that to a boolean. Essentially if the pipeline evaluates to a non-empty result, the result is $true otherwise it is $false. This is probably not what you intended.
Try this:
$today=(Get-Date).AddDays(-1).ToString("yyyy-MM-dd")
foreach ($item in $list.items) {
[DateTime]$CreatedDate=$item["Created"]
$convertedCreatedDate=$CreatedDate.ToString("yyyy-MM-dd")
if ($convertedCreatedDate -eq $today) {
Write-Host $item["Created"]
}
}