Set Expiry Date with CSV containing DD-MMM-YYYY format - powershell

Our HR Department's Termination system sends us a report at intermittent intervals of people who are leaving/people who have left.
Import-Csv -Path \C\Users\Leaver.csv | ForEach-Object {
$EmployeeNumber = $_.EmployeeNumber
$TerminationDate = $_.TerminationDate
$objADUser = (Get-ADUser -Filter {employeeid -eq $EmployeeNumber}).samAccountName
}
The report that HR give us doesn't have their sAMAccountName or even their email. Fortunately, it does have their Employee ID. I'm using this in the script to get their SAM name since I figure that's easier to work with.
Problem is, the termination date they give is actually the last day they work, not the first day of non-work.
Normally I'd have
Set-ADAccountExpiration -Identity $objADUser -DateTime "$TerminationDate"
But that means they can't work on their last day. I also can't add a time like "23:59:59" as Powershell doesn't seem to like that with a variable.
There's also the fact that the date format is in DD-MMM-YYYY (EG 01-Jan-2000) which does make it difficult to work with.
Anyone know what the best syntax to use here is?

Related

Trying to export tickets/incidents from SCSM to csv file using powershell

I am trying to do a simple ticket/incident file export using PowerShell. All of our tickets go into the Service manager 2019 Console.
What I am trying to do is be able to filter and export our tickets using certain date range. Our senior system engineer was able to help me get started and I am trying to figure out the best way to do this. So this is what he sent me:
____________________________________________
you always want to filter / where as far left as possible to reduce processing overhead
also Tab is your friend when typing cmdlets - usually something like
Get-SCSMIncident -<Tab>
and it will show you your options
or Get-SCSMIncident -Help
you can also use Where-Object to filter once you have the correct subitems
Get-SCSMIncident | Where-Object {$_.Status -eq "Active"}
because you're doing the filter AFTER Get-SCSMIncident, it's going to find ALL incidents in the background, THEN filter them (slow/bad)
____________________________________________
So I tried a few things. He suggested to do the following below, create variables, store them and pull the data later.
$allincidents = Get-SCSMIncident
$resolved = $allincdients | Where-Object {$_.Status -eq "Resolved"}
$active = $allincdients | Where-Object {$_.Status -eq "Active"
Then I would export the info such as below to a csv file
$active | export-csv c:\temp\scsm_incidents.csv -nti
The issue is that when I execute it, the initial storing of the variables it is taking too long, because we have obviously thousands and thousands of tickets.
I then thought what if I did the following below
Create the date variables first and store them.
$startDate = Get-Date -Year 2022 -Month 1 -Day 1
$endDate = Get-Date -Year 2022 -Month 2 -Day 2
Get-SCSMIncident | Where-Object {($_.createddate.date -le $endDate) -and ($_.createddate.date -ge $startDate)} | Export-Csv C:\Temp\SCSM-tickets.csv -nti
And given the logic that my Senior Engineer told me, it is going through all the tickets first because of the Get-SCSMIncident and then filtering and then storing into an csv file.
So my question is there a way to sort of go backwards? I know computer language wise it wouldn't make sense because it doesn't know what object it is being pointed to.
Like for example
Where-Object {($_.createddate.date -le $endDate) -and ($_.createddate.date -ge $startDate)} | Get-SCSMIncident | Export-Csv C:\Temp\SCSM-tickets.csv -nti
The end result is that I want to be able to pull data on a weekly basis using just a date range, without have to run through all the tickets every time. Since new tickets are being generated everyday, each time I run through it, it will take longer and longer and longer. I am by no means expert with powershell at all and looking for any insight on export data files much simpler or faster. If anyone has any ideas I would greatly appreciate it.
FYI I know I can pull each ticket at a time, our naming scheme used is INC##### so for example to pull any ticket
Get-SCSMIncident -id "INC10105"
This would pull up this one ticket in powershell.
I don't know all the powershell commands and searching through the library is confusing
If anyone knows a way of how to do something like this pulling tickets in sets that would be helpful.
Get-SCSMIncident -id "INC00001" TO -id "INC00500" | Export-Csv C:\Temp\SCSM-tickets.csv -nti
Or evening pulling data by date.
Apologize for the super long post. Also if anyone knows how to export tickets in Service Manager Console please let me know too!!! I searched everywhere and seems like I can't export anything
As stated in my comments, unless the cmdlet Get-SCSMIncident has filtering by DateTime range capabilities, it is unlikely that there is a way around having to go through all the collection, however, there are ways the code could be improved so it can do the filtering faster. A foreach loop (enumeration) loop in addition to an if condition (filtering condition) is much faster than Where-Object.
$startDate = Get-Date -Year 2022 -Month 1 -Day 1
$endDate = Get-Date -Year 2022 -Month 2 -Day 2
$incs = foreach($inc in Get-SCSMIncident)
{
if($inc.CreatedDate -gt $endDate -or $inc.CreatedDate -lt $startDate)
{
# If the Incident's CreatedDate is greater than `$endDate` OR
# lower than `$startDate` go to the next Incident.
# In other words, skip this Incident.
continue
}
[pscustomobjct]#{
ID = $inc.ID
Status = $inc.Status
Title = $inc.Title
Description = $inc.Description -replace '\r?\n', ' '
AffectedUser = $inc.AffectedUser
AssignedTo = $inc.AssignedTo
CreatedDate = $inc.CreatedDate
TierQueue = $inc.TierQueue
Urgency = $inc.Urgency
Priority = $inc.Properity
}
}
$incs | Export-Csv path/to/exported.csv -NoTypeInformation

How to change multiple telephone numbers in AD from a CSV

Good Morning Everyone,
I have a list of users (about 200 samAccountName's) and the only field that needs to be updated in AD is the telephoneNumber field. Example user John Smith Telephone number is 44444 and needs to be changed to 12345. Im guessing the csv file would contain a column for samAccountName, and the 2nd column would be telephoneNumber which would be a list of the numbers that are going to overwrite whatever the users current number is in AD.
i was thinking i could use the script from #Henrik Stanley Mortensen and modify it, but not sure what fields to change. THis is the url from my 1st question....
How to edit only the Firstname (givenName) of multiple users and import with csv
First let me say I agree stack is not a code generation site. It goes a long way if you have a little bit of code to show as to what you have tried. Even if it is TERRIBLE others in the community will feel compassion and empathy towards you versus negativity. Second please go to amazon and buy the book "Learn Powershell in a Month of Lunches" This will help you a ton and get your fundamentals down. Real easy read.
https://www.amazon.com/Learn-Windows-PowerShell-Month-Lunches/dp/1617294160/ref=sr_1_3?ie=UTF8&qid=1533311287&sr=8-3&keywords=powershell+books
Ok now off my soapbox. So I have created a csv called updatetelphones.csv and placed it in my C:\temp folder on my desktop. It has two columns one called SamAccountName and a second Called TelephoneNumber. Notice no spaces. With powershell we want to import that into a variable then iterate through each item and set the phone number for the user.
$UsersToUpdate = import-csv -Path "C:\temp\updatetelephones.csv"
foreach($User in $UsersToUpdate)
{
Set-ADUser -Identity $User.SamAccountName -OfficePhone $User.TelephoneNumber -WhatIf
}
Above is the powershell code. Now look carefully at the end of my set-aduser command I have a -whatif. ANYTIME you are making changes to AD I recommend you test your script with the -whatif first. That simulates the changes but doesn't make any so you can confirm it is accurate. So use this to test on your side. Once you validate remove the "-whatif" and run to actually make the changes. Peace and Happy powershell learning!!
it is strange, I use telephonenumber as a Get-ADUser property but OfficePhone as a parameter to set the telephonenumber property
Set-AdUser -Identity $user.SID -Credential $credential -OfficePhone $vp_telephonenumber -Server DC2.abc.com

Working with dates in extensionAttributes and Get-Date

I'm attempting to use Active Directory extensionAttributes to keep track of certain dates (like start date, termination date, etc) so that I can trigger certain actions when that date occurs.
I'm having an issue with the different variations that a date can be entered in (M/D/YY, MM/DD/YY, MM/DD/YYYY, etc). For example, I can use Get-Date to output to a format of M/D/YYYY, but I run into issues when someone enters MM/DD/YY.
Is there a way to make this work so that it can accept other variations (as long as it's month/date/year)?
Here are a couple of lines from the script in question. This runs once a day, and checks for new users starting the following day.
$StartingOn = (Get-Date).AddDays(1).ToShortDateString()
$NewUserCheck = Get-QADUser -DontUseDefaultIncludedProperties -IncludedProperties extensionAttribute11 | where { $_.extensionAttribute11 -eq $StartingOn }
Notice how it only returns as long as the date equals the Get-Date output. It was the only way I was able to get this to work properly. Even at that, if someone typed in 07/20/15, the output would return nothing.
Don't try to compare date strings. Use DateTime comparison which won't care about formatting details e.g.:
$StartingOn = (Get-Date).AddDays(1)
$NewUserCheck = Get-QADUser -DontUseDefaultIncludedProperties -IncludedProperties extensionAttribute11 |
Where { [DateTime]($_.extensionAttribute11) -eq $StartingOn}

Powershell Query AD to export emails of all users in .txt file?

I would like to write a PS script that exports a .csv for all users that are specified in a separate .txt file. So, for instance, I could create a text file that has
Timmy Turner
Silly Sally
Then, when the script is ran, it searches AD for those two users and exports a CSV with their first name, last name, and email address.
I originally got hung up a bit on how the "Get-ADUser" filter worked, but I produced something semi-usable. However, what I've come up with just asks who you are searching for and then uses that. I think it would be much easier to just have it reference a pre-made text file, especially when searching for a large number of users. Or, there may be an even easier way to do this that I am not thinking of. Here is what I currently have:
$SamAc = Read-Host 'What is the first and last name of the person you would like to search for?'
$filter = "sAmAccountname -eq ""$SamAc"""
Get-ADUser -Filter $filter -Properties FirstName, LastName, EmailAddress | select FirstName, LastName, EmailAddress | Export-CSV "C:\Scripts\PS_ADQuery\Email_Addresses.csv"
I feel like the "Get-Content" cmdlet is close to what I am looking for, but I can't seem to get it to function correctly. I may be going in the totally wrong direction, though.
I found the answer. It turns out I even had the AD properties totally wrong. Take my comments with a grain of salt since I may not fully understand the processes behind each line of code, but this does exactly what I was looking to do.
#creates a $users variable for each username listed in the users.txt file. the ForEach
#command allows you to loop through each item in the users.txt array. the scriptblock
#nested into the ForEach command queries each username for specific properties.
$users = ForEach ($user in $(Get-Content C:\Scripts\PS_ADQuery\users.txt)) {
Get-AdUser $user -Properties GivenName,sn,mail
}
#takes the $users variable defined by the ForEach command and exports listed properties
#to a csv format.
$users |
Select-Object GivenName,sn,mail |
Export-CSV -Path C:\Scripts\PS_ADQuery\output.csv -NoTypeInformation

PowerShell: Compare CSV to AD

I'm fairly new to PowerShell and I'm posting this on many forums but I've had success with programming assistance from here before and although this isn't strictly programming, I was hoping someone might know the answer.
My organization had about 5,300 users we needed to disable for a client. Someone decided the best use of our time was have people go through AD and disable them one at a time. Soon as I got wind of this I put a stop to it and used PowerShell to take the CSV list we already had, and ran a cmdlet to disable all of the users in the CSV list.
This appeared to work, but I wanted to run a comparison. I want to compare the users from the CSV file, to the users in AD, and confirm that they are all disabled without having to check all 5300 individually. We checked about 60 random ones to verify my run worked, but I want to make sure none slipped through the cracks.
I've tried a couple scripts and I've tried some variations of cmdlets. None of the scripts I tried even worked, spammed with errors. When I try to run a search of AD either using get-content or import-CSV from the csv file, when I export its giving me about 7600 disabled users (if I search by disabled). There were only 5300 users in total, so it must be giving me all of the disabled users in AD. Other cmdlets i've run appear to do the same thing, its exporting an entire AD list instead of just comparing against my CSV file.
Any assistance anyone can provide would be helpful.
Without knowing the exact structure of your CSV I'm going to assuming it is as such:
"CN=","OU=","DC="
"JSmith","Accounting","Foo.com"
"BAnderson","HR","Foo.com"
"JAustin","IT","Foo.com"
That said, if your first field actually has CN= included (i.e. "CN=JSmith","OU=Accounting","Foo.com") you will want to trim that with .TrimStart("CN=").
$ToRemove = Import-CSV UserList.csv
$UserList=#()
ForEach($User in $ToRemove){
$Temp = ""|Select "User","Disabled"
$Temp.User = $User.'CN='
If((Get-aduser $Temp.User -Prop Enabled).Enabled){$Temp.Disabled='False'}else{$Temp.Disabled='True'}
$UserList+=$Temp}
$UserList|?{$_.Disabled -eq 'False'}
That loads the CSV into a variable, runs each listing through a loop that checks the 'CN=' property, creates a custom object for each user containing just their name and if they are disabled, and then adds that object to an array for ease of use later. In the end you are left with $UserList that lists everybody in the original CSV and if they are disabled. You can output it to a file, filter it for just those that are still enabled, or whatever you want. As noted before if your CSV actually has CN=JSmith for each line you will want to update line 5 to look as such:
$Temp.User = $User.'CN='.TrimStart("CN=")
If you don't have any headers in the CSV file you may want to inject them. Just put a line at the top that looks like:
CN=,OU=,DC=
Or, if you have varying OU depths you may be better off doing a GC and then running each line through a split, taking the first part, trimming the CN= off the beginning, and checking to see if they are disabled like:
GC SomeFile.CSV||%{$_.split(",")[0].trimstart("CN=")|%{If((get-aduser $_ -prop enabled).enabled){"$_ is Enabled"}else{"$_ is Disabled"}}}
Assuming your CSV has a column called DN you can run the following which will return all users from your spreadsheet which are enabled
import-csv YourUsersCSV.csv | Get-ADUser -Filter
{DistinguishedName -eq $_.DN } |
where{$_.enabled -eq $true} |
Select-Object -Property DistinguishedName,samaccountname,enabled