Sharepoint Powershell Form Library - Compare Date, Change Value - sharepoint

I don't have much knowledge of Sharepoint Powershell but I'm attempting to piece something together to automate the checking of expiry date fields inside an infopath form library vs today's date.
I wish to compare every date in the following column,
Construction_x0020_Card_x0020_Expiry
To today's date. If the value is less or is null than today's date (meaning expired licence or no licence) modify the text in the following field:
Construction_x0020_Card_x0020_Type
This is what I have so far;
if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null) {
Add-PSSnapin "Microsoft.SharePoint.PowerShell"
}
$webUrl = "https://####"
$listDisplayName = "HR Employee Record"
$ExpiryDate = #($Construction_x0020_Card_x0020_Expiry)
?? Not sure if this works,$Construction_x0020_Card_x0020_Expiry is an array?
$TodayDate = (Get-Date).ToString("dd-MM-yyyy")
$convertedExpiryDate = $ExpiryDate.ToString("dd-MM-yyyy")
?? Not sure if this works, $Construction_x0020_Card_x0020_Expiry is System.Object[] trying to convert to System.DateTime
foreach ($item in $convertedExpiryDate.items | where {$convertedExpiryDate -lt $TodayDate}) {
if ($convertedExpiryDate -eq $null) {
Write-Host #($Construction_x0020_Card_x0020_Type)["$null"]
} elseif ($convertedExpiryDate -lt $TodayDate) {
Write-Host #($Construction_x0020_Card_x0020_Type)["Expired"]
} elseif ($convertedExpiryDate -ge $TodayDate) {
Write-Host #($Construction_x0020_Card_x0020_Type)["Valid"]
}
}
Thanks,
Lance

Related

list all vendors in azure ad who had logged/never logged in the past 24 hours

I wrote a script to list all vendors in the azure ad to check if they are working or not. the script find the logged in users for the past day and if there is a record it should print, if there is no record and the vendor did not logged in or work it should print no login records. but my script is not working well any one can help?
###########################Here is the code ##################
#get azure ad users
$AzADUsers = get-azureaduser
#start for loop
foreach ($user in $AzADUsers){
#list attributes
$dp = $user.DisplayName
$company = $user.CompanyName
# list of contractors/vendors who didn't log in during the day.
if ($company -eq "Vendor Resource - companyname1" -or $company -eq "Vendor Resource - companyname2" -or $company -eq "Vendor Resource - companyname3") {
#check if they logged in the past 24 hours
$SetDate = (Get-Date).AddDays(-1);
$SetDate = Get-Date($SetDate) -format yyyy-MM-dd
$AllSiginLogs = Get-AzureADAuditSignInLogs -Filter "createdDateTime gt $SetDate"
$LoginRecord = $AllSiginLogs | Sort-Object CreatedDateTime -Descending
if($LoginRecord.Count -gt 0){
$lastLogin = $LoginRecord[0].CreatedDateTime
}
else{
$lastLogin = 'no login record | Sick'
}
Write-Host "Last logon time : " $lastLogin $dp $company
Write-Host " "
}
}
in addition to our discussion:
Currently you loop through the $AzAdUsers and query foreach the SignInLogs. But you do not filter the SignInLogs for the specific user, you query all the time the same information and select the latest entry from that log, but it has no relation to the current user.
You have to filter the SignInLog for the specific user, e.g.:
$AllSiginLogs = Get-AzureADAuditSignInLogs -filter "Id eq '$($user.Id)' and createdDateTime gt $SetDate"
After that you could do:
$attrsht = #{
userId=$User.id
DisplayName=$user.displayname
LastSignIn=$LoginRecord.CreatedDateTime
}
new-object -typename psobject -property $attrsht
Btw. the AzModule will be replaced by the microsoft.graph modules. So it might be the right time to do the switch, which you have to do in any case until 2024.
If you do so, you can directly get the lastSignInDateTime from the user object:
#Switch to beta API
select-mgprofile -name beta
$lastSignIn = get-mguser -userId $user.id -Property signinactivity
$lastSignIn.LastSignInDateTime
In regards to you latest comment:
once again, if you want to know the last signInDateTime for a specific user you have to filter for that user id. if you filter by companyname you will probably get several users back and then you have to loop over this array of users and query the signInLog foreach user. the problem you are facing is that you miss to specify consistensylevel and countvariable, e.g.:
$company = "MyCompanyName"
$users = Get-MgUser -filter "companyname eq '$company'" -ConsistencyLevel eventual -CountVariable $null -property Id,CompanyName,DisplayName
select-mgprofile -Name beta
$lastSignInDateTime = #(
foreach ($user in $users){
$LoginRecord = get-mguser -userId $user.id -Property signinactivity
$attrsht = #{
userId=$User.id
DisplayName=$user.displayname
CompanyName=$user.CompanyName
LastSignIn=$LoginRecord.signinactivity.LastSignInDateTime
}
new-object -typename psobject -property $attrsht
}
)
You need to have the MgGraph module installed to run the above mentioned cmdlets -> install-module microsoft.graph
More information in regards to consistensylevel:
https://devblogs.microsoft.com/microsoft365dev/build-advanced-queries-with-count-filter-search-and-orderby/

Issues pulling value of cell using excel com objects in powershell

I am writing a script that scans each cell in an excel file for PII. I've got most of it working, but I am experiencing two issues which may be related.
First of all, I am not convinced that the "Do" loop is performing as intended. The goal here is if the text in a cell matches the regex string, create a PSCustomObject with the location information, then use the object to add a line to a csv file.
It appears that the loop is running for every file, regardless of whether or not it actually found a match.
The other issue is that I can't seem to actually pull the cell value for the matched cell. I've tried several different variables and methods, the latest attempt being "$target.text," but the value of the variable is always null.
I've been racking my brain on this for days, but I'm sure it'll be obvious once I see it.
Any help here would be appreciated.
Thanks.
$searchtext = "\b(?!0{3}|6{3})([0-6]\d{2}|7([0-6]\d|7[012]))([ -]?)(?!00)\d\d\3(?!0000)\d{4}\b"
$xlsFiles = Get-ChildItem $searchpath -recurse -include *.xlsx, *.xls, *.xlxm | Select-object -Expand FullName
$Excel = New-Object -ComObject Excel.Application
$excel.DisplayAlerts = $false;
$excel.AskToUpdateLinks = $false;
foreach ($xlsfile in $xlsfiles) {
Write-host (Get-Date -f yyyymmdd:hhmm) $xlsfile
try{
$Workbook = $Excel.Workbooks.Open($xlsFile, 0, 0, 5, "password")
}
Catch {
Write-host $xlsfile 'is password protected. Skipping...' -ForegroundColor Yellow
continue
}
ForEach ($Sheet in $($Workbook.Sheets)) {
$i = $sheet.Index
$Range = $Workbook.Sheets.Item($i).UsedRange
$Target = $Sheet.UsedRange.Find($Searchtext)
$First = $Target
Do {
$Target = $Range.Find($Target)
$Violation = [PSCustomObject]#{
Path = $xlsfile
Line = "SSN Found" + $target.text
LineNumber = "Sheet: " + $i
}
$Violation | Select-Object Path, Line, LineNumber | export-csv $outputpath\$PIIFile -append -NoTypeInformation
}
While ($NULL -ne $Target -and $Target.AddressLocal() -ne $First.AddressLocal())
}
$Excel.Quit()
}
Figured it out. Just a simple case of faulty logic in the loops.
Thanks to everyone who looked at this.

Extracting most recent activity/logon date

I am extracting computers from our Azure portal and I am specifically looking for devices which have had no activity in over 120 days.
The issue every time I extract this info it only gives me the activity/logon of the initial registration for the device.
Some of our devices have multiple registrations as they are passed from user to user.
So when I extract the info it is not accurate.
I used the below which I thought should work but I still get the devices that have newer activity than my target date. I also see an error when I am running the script I have include that below beneath the code I have used.
Could someone assist I feel I am close.
clear-host
$maxDate = Get-Date '6/1/19'
#Create a hash table to remove dupes
$set = #{}
#create our final array
$cleanSet = #()
#load data
$data = Get-MsolDevice -All | select-object -Property ObjectID, ApproximateLastLogonTimestamp, DisplayName
#for each item in the pipeline, add it to our hash table
foreach($_ in $data) {
#if the item isn't in the hash table, add it
if(!$set.Contains($_.ObjectID)) {
$set.Add($_.ObjectID, $_)
}
else {
#if we have a more recent date for the item, update the date so we only have the most recent one
if((Get-Date $_.ApproximateLastLogonTimestamp) -gt (Get-Date $set[$_.ObjectId].ApproximateLastLogonTimestamp)) {
$set[$_.ObjectID].ApproximateLastLogonTimestamp = $_.ApproximateLastLogonTimestamp
}
}
}
#now that we have the most recent date for each item, remove ones newer than our target date.
$set.GetEnumerator() | ForEach-Object{
if((get-date $_.Value.ApproximateLastLogonTimestamp) -lt $maxDate) {
$cleanSet += $_.Value
}
}
$cleanSet | select-object -Property ObjectID, DisplayName | export-csv "C:\Users\tesyuser\Desktop\Project Work\Stale machine on Azure\Exported CSV\2HIE-Stale-Device-List.csv" -NoTypeInformation
error
Get-Date : Cannot bind parameter 'Date' to the target. Exception
setting "Date": "Cannot convert null to type "System.DateTime"." At
line:29 char:18
Hi So my code should now look like this?
$maxDate = Get-Date '6/1/19'
#Create a hash table to remove dupes
$set = #{}
#create our final array
$cleanSet = #()
#load data
$data = Get-MsolDevice -All | select-object -Property ObjectID, ApproximateLastLogonTimestamp, DisplayName
#for each item in the pipeline, add it to our hash table
$data | ForEach-Object {..} {
#if the item isn't in the hash table, add it
if(!$set.Contains($_.ObjectID)) {
$set.Add($_.ObjectID, $_)
}
else {
#if we have a more recent date for the item, update the date so we only have the most recent one
if((Get-Date $_.ApproximateLastLogonTimestamp) -gt (Get-Date $set[$_.ObjectId].ApproximateLastLogonTimestamp)) {
$set[$_.ObjectID].ApproximateLastLogonTimestamp = $_.ApproximateLastLogonTimestamp
}
}
}
#now that we have the most recent date for each item, remove ones newer than our target date.
$set.GetEnumerator() | ForEach-Object{
if((get-date $_.Value.ApproximateLastLogonTimestamp) -lt $maxDate) {
$cleanSet += $_.Value
}
}
$cleanSet | select-object -Property ObjectID, DisplayName | export-csv "C:\Users\birrelld\Desktop\Project Work\Stale machine on Azure\Exported CSV\3HIE-Stale-Device-List.csv" -NoTypeInformation

Failure to compare values when I am reading from CSV file

My PowerShell script is as follows, I have got all the sites in farm saved as CSV file using Export-Csv command.
$farmList = Import-Csv "TestFarm.csv"
$farmList1 = Import-Csv "OtherFarm1.csv"
foreach ($site in $farmList)
{
Write-Host "db - ", $site
foreach ($farmsite in $farmList1)
{
if ($site -eq $farmsite) {
Write-Host "matching site found for ", $farmsite
break
}
Write-Host "farm - ", $farmsite
}
}
My Excel files in CSV looks like
Site
/sites/TestSite
/sites/testsite1234
...
The second Excel file in CSV looks like
Site
/sites/TestSite
/sites/testsite1234
...
When I debug the program, I am getting a value of $site and $farmSite as
#{Site=/sites/TestSite} , but when I compare the values using -eq, the values do not match.
I have also tried using Compare-Object without success.
You need to compare the objects' Site properties instead of the objects themselves.
Change this:
if ($site -eq $farmsite) {
into this:
if ($site.Site -eq $farmsite.Site) {
If the files contain just this one property you could also expand it on import:
$farmList = Import-Csv "TestFarm.csv" | Select-Object -Expand Site
$farmList1 = Import-Csv "OtherFarm1.csv" | Select-Object -Expand Site
The latter would also allow you to simplify your code by using a -contains check:
foreach ($farmsite in $farmList1) {
if ($farmList -contains $farmsite) {
Write-Host "matching site found for $farmsite"
}
}

Export to csv after loop ends with powershell

I have the following powershell scripts that iterates through all list items and workflows, trying to find old running workflows
The logic is OK, but I need to be able to export to to csv with the columns
ListeItemUrl, ListItemName, Nr of Days Opened.
$web = get-spweb https://mysite.com/sites/billing
$list = $web.Lists["Bill Cycles"]
$count = 0
foreach($wf in $list.WorkflowAssociations)
{
if ($wf.Name -like "*Previous Version*")
{
Write-Host 'Bill Cycles with old workflow: ' $wf.Name
foreach($listitem in $list.Items)
{
if($listitem.ContentType.Name -eq "Bill Cycle")
{
$workflows = $listitem.Workflows
foreach($Workflow in $listitem.Workflows)
{
if($Workflow.AssociationId -eq $wf.Id)
{
$count = $count+1
Write-Host $listitem.Name
Write-Host 'https://mysite.com/sites/billing/'$listitem.Url.TrimStart();
Write-Host 'Workflow opened for: ' ((Get-Date) - $Workflow.Created).Days
}
}
}
}
}
}
Write-host 'Count: ' $count
Then with the exported file I can easily sort by nr of days and deliver the report I need.
Format your output as a csv - ListeItemUrl, ListItemName, NrofDaysOpened - and pipe it to Export-Csv cmdlet( you can find out more by running get-help Export-Csv). You will have to change Write-Host to Write-Output

Resources