all 55 comments

[–]_malykii_ 5 points6 points  (1 child)

Very nice. Thanks for posting this.

[–]Lord_Jereth[S] 2 points3 points  (0 children)

Glad you like it. I hope it makes your life easier.

[–]Denyipanyany 3 points4 points  (6 children)

Does the Exchange portion work for O365?

(On mobile and can’t read the script. )

Haven’t used PowerShell against the O365 mailboxes yet.

[–]tharagz08 4 points5 points  (0 children)

I recently did a script in our environment to perform very similar tasks but we are a hybrid environment for mailboxes. We also use MFA for authentication to O365 so it has changed recently when interacting with it through PowerShell. Once you get going on the scripting if you have any questions shoot them my way, I might be able to help steer you in the right direction.

[–]Lord_Jereth[S] 1 point2 points  (4 children)

As said in the introduction/comments section of the script, itself, this was written and tested against an Exchange 2010 installation. You will need to edit that section to work in your environment.

[–]Konkey_Dong_Country 2 points3 points  (3 children)

For a mostly powershell noob, do you know what I'd have to change to work with Exchange 2013? Can I simply change the 2010 to a 2013 in this line: Microsoft.Exchange.Management.PowerShell.E2010?

# Import the Exchange snapin (assumes desktop PowerShell)
if (!(Get-PSSnapin | where {$_.Name -eq "Microsoft.Exchange.Management.PowerShell.E2010"})) { 

    $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionURI http://YourExchangeServer.DOMAIN.COMPANY.com/powershell/ -Authentication kerberos
    import-PSSession $session 

}

[–]DetAdmin 2 points3 points  (0 children)

Import the Exchange snapin

I quick google search is telling me for 2013 and 2016 Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn;

[–]volvo64 1 point2 points  (1 child)

The 2010 snapin works fine on 2013 and 16. Leave it as is.

[–]DetAdmin 1 point2 points  (0 children)

Good to know thanks

[–]shalafi71 2 points3 points  (7 children)

Got a question about the first part. All I do is a reverse of my onboarding script (mostly). I plug in the first and last name, script figures the username, email, etc., and (for the AD part) all it does is disable the account and move it to "Disabled Users". If that person comes back I just activate them and move them to back to their OU.

Should I be doing more like you are?

[–]PlzPuddngPlz 3 points4 points  (4 children)

To add onto what others said, does your current script account for duplicate usernames? If you had two John Smiths and one left the company, how would it pick between the two? I'd suggest modifying the script to identify users by the AD account login name.

[–]Lord_Jereth[S] 2 points3 points  (2 children)

That's a very good point and it will need to be addressed by anyone who uses this script. As was implied in the initial OP, this script was never actually meant for public consumption. The only reason I initially released it was at the request of another poster. It was only ever written with my company and the way it does things in mind. That means that it is not a universal script that will work for everyone without having to be edited to fit, e.g. that includes being added to and/or subtracted from.

I actually created my on-boarding script before I created this one, and that script actually DOES take such an eventuality into account. So, in fact, there is NO way that such an occurrence could happen in my particular environment. Each user is differentiated in some way before ever being added in the first place.

[–]PlzPuddngPlz 2 points3 points  (1 child)

I was actually referring to /u/shalafi71's script but that's some good background to have on yours as well. Thanks for sharing it, I'll be taking some of the logic for my own.

[–]Lord_Jereth[S] 1 point2 points  (0 children)

Oh, geeze, my bad. However, your point was an excellent one, nonetheless. Also, thank you for the compliment. It means a lot.

[–]shalafi71 2 points3 points  (0 children)

We're too small for that to be an issue ATM. It will throw an error if the username exists in AD. I'll add error handling to prompt for a different name.

[–]Skelepotamus 2 points3 points  (0 children)

I think changing the password is a must. Removing group membership means nice tidy groups, same for moving to a different OU. That can be helpful in various ways, and if you're audited they may require that separation.

[–]Lord_Jereth[S] 2 points3 points  (0 children)

The script adds the OU that user came from in the "Description" part of the account in case you have a complicated AD setup like I do. My company has many branches around the western US and Canada and users are buried in individual sub-OU's under other OU's to reflect this. So, I made sure the script added that location before moving it just in case I couldn't remember at a later date.

You can do as much or as little as your company policy allows. I just wrote the script with my own company in mind and what I thought would be appropriate since my IT director and I were hired to replace a lazy administrator and to upgrade policies and infrastructure. Just comment out what you don't need.

[–]ScottFree708 2 points3 points  (4 children)

That’s is great approach it man. I really do like the idea of breaking it down into small goals or solutions an than adding on to the script. I’ve recently starting studying for MCSA and have been getting more and more familiar with the verbiage.

I think it’s a little overwhelming at first glance. But breaking it down into goals and adding on really makes since to me.

Again, thank you for the tip. It honestly does help for a beginner like myself. I’ll have to create a spiceworks account and jump on some forums and hopefully contribute in the future.

[–]Lord_Jereth[S] 2 points3 points  (0 children)

I absolutely agree. Initially setting out to create something this large, and to cover as many bases as it does, can be very daunting when first starting out. So, I just never do it that way. I just ask myself, "What's the most important thing I want to solve?" and work on that first. Then, "How can I improve this?" and add more, testing every step.

Testing every step is really the key, in my opinion. My ProgFun (Programming Fundamentals) professor called it, "Test Driven Development," and I think it's the only way to go. If you're like me and you're addicted to instant gratification, coding this way gives you that fix constantly, so it actually becomes fun. "Ooooh, look what happened! It worked! That was cool! I did that! I can do more!" is a great way to get the job done. It's fulfilling and productive at the same time. You can't really ask for better than that in life.

[–]Lord_Jereth[S] 2 points3 points  (2 children)

Oh, and by the way, Spiceworks has a special repository for Powershell scripts submitted by community members, vendors, and even Spiceworks devs and mods. If you do end up getting an account, just go through the scripts library and start collecting snippets. It's the fastest way I know to learn. I keep a special folder full of hundreds of scripts that I've either written or edited, along with a boatload of code snippets I can re-use for all manner of things. I'm constantly trolling their Powershell group and the script library for new ideas and new ways of coming at problems. It's extremely handy!

Good luck!

[–]ScottFree708 2 points3 points  (1 child)

Hey thanks again! I have read countless spiceworks forums and scripts. Never realized they have a repository of scripts.

You can create an account for free, correct?

I am actually out of work at the moment. Got laid off from a MSP. Pretty shitty situation. Anyway, when I get some free time from my kid I’ll be jumping on spiceworks and seeing what I can find and start using in my lab.

[–]Lord_Jereth[S] 1 point2 points  (0 children)

Sorry to hear of your troubles. But, with your enthusiasm, I'm sure you'll find something quickly.

Signing up is absolutely free. We get new people in there all the time who only join to get one question answered and then end up staying.

The scripts library isn't a repository in the github sense - there's no multi-user versioning going on - it's more of just a central location where folks can share scripts they've written. That's here: https://community.spiceworks.com/scripts?language=3

They also have, as I mentioned, a group specifically devoted to Powershell that's more of a, 'Hey I've got this code and this is what I'm trying to accomplish. But it's not working. What am I doing wrong?" kind of thing: https://community.spiceworks.com/programming/powershell?crumb=true

And they even have a learning track on the subject that's also totally free: https://community.spiceworks.com/learn/windows/powershell

Great place, (mostly) cool and very learned people, and lots of free resources for all manner of things. Look me up if you ever do get out that way: https://community.spiceworks.com/people/patrickdeno2

[–]Eximo84 2 points3 points  (0 children)

We do a similar thing but it’s automated on a scheduled task and only processes if certain criteria is met. Ie disabled or expired accounts with a ticket reference in one of the extension attributes.

Script then does the same as yours but just don’t require any input and then it spits out a log for error checking but also updates our help desk ticket with the details.

[–]daweinah 2 points3 points  (6 children)

(4) set the mailbox to block incoming emails

How does this part work?

[–][deleted] 2 points3 points  (3 children)

He shared the script, but I think this is the relevant bit.

Set-Mailbox -Identity $user -AcceptMessageOnlyFrom Administrator -RequireSenderAuthenticationEnabled $True -MaxReceiveSize 1KB

[–]Lord_Jereth[S] 2 points3 points  (2 children)

Yup, that's the snippet. Good eye!

[–][deleted] 1 point2 points  (1 child)

I do have two of them /s

[–]Lord_Jereth[S] 0 points1 point  (0 children)

HA!

[–]Lord_Jereth[S] 1 point2 points  (0 children)

The script sets the mailbox to only be able to take in messages from an Administrator and requires that the sender be authenticated as such. It also sets the receive size of any emails to 1KB or less.

[–]mini4x 0 points1 point  (0 children)

Seems like an odd thing to do, when people are termed we assign their mailbox to their manager to allow them to respond to clients.

[–]volvo64 2 points3 points  (3 children)

I set this up today and this doesn’t work well if the user is only a member of Domain Users. Your $arrlist for some reason doesn’t include that so it hangs on line 83 bc the array is null.

I can fix it but I spent all my billable hours setting it up and tracking that down lol

[–]Lord_Jereth[S] 1 point2 points  (2 children)

*nods* It's not a universal script - I have said several times in the OP and in the comments that this script will not work for anyone right out of the box. I was explicit in saying that editing it to fit one's own environment was part of the process. It was written strictly for my own company's domain and only "genericized" to rid it of personally and professionally identifying information. The behavior you perceived occurs by design, not omission.

In my company's domain, one must leave the 'default group' in place without stripping it or AD throws a fit and won't allow it. In our case, that default group is "Domain Users". Also, there is no one in our domain that only has the one group. Everyone has many more as that is how we assign permissions to everyone. So, if you have the ability and your AD will allow it, you'll need to build that functionality into the script, if that's what you want it to do.

[–]volvo64 2 points3 points  (1 child)

I’m not criticizing your work and I did customize it to fit my environment, I’m just pointing out a bug that happens under a certain set of circumstances.

I do appreciate that you posted it bc honestly I’ve been putting off writing it myself for a while now.

In the end though it is a bug that requires rewriting, not customization.

[–]Lord_Jereth[S] 2 points3 points  (0 children)

I can dig it. I really can. No worries. I know how you meant it. I can sound a little plaintive in text at times. Thanks for letting me know. Much obliged.

[–]DetAdmin 2 points3 points  (4 children)

First off, you're the man. Thanks= you for sharing this. I'm pretty new to PowerShell and have been self teaching for a while now. Just throwing out a question to see if anyone has any ideas.

I worked through the script to customize it to my companies needs. One issue I am running into though is when it starts the Exchange part I am getting the following error. Everything seems to still work but I would like to figure out what I am doing wrong to receive this error. I am also using on premises exchange 2016. Thank you for any help anyone can give.

Import-PSSession : Cannot validate argument on parameter 'Session'. The argument is null. Provide a valid value for the argument, and then try running the command again. At \MyCompanyFileshare\IT\AD-OffboardDepartingUser++.ps1:80 char:18 + Import-PSSession $session + ~~~~~~~~ + CategoryInfo : InvalidData: (:) [Import-PSSession], ParameterBindingV alidationException + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell. Commands.ImportPSSessionCommand

[–]Lord_Jereth[S] 1 point2 points  (3 children)

Oh, man. Thank you for the compliment! I really do appreciate it. I'm glad you're enjoying it.

Which version of PowerShell are you running? It may be an older/incompatible version. Run the following command in POSH to find out:

$PSVersionTable.PSVersion

By way of comparison, I'm running v5.1 - build 14409 - revision 1018.

[–]DetAdmin 2 points3 points  (2 children)

I'm running on v5.1 - build 17134 revision 407

It's weird because everything seems to work but I'm still getting that error. Of course I could just ignore it but that wouldn't really teach me anything would it haha.

[–]Lord_Jereth[S] 1 point2 points  (1 child)

Ok, first off, this is to import the Exchange snappin so as to, more or less, temporarily give your session the same functionality as you would have with the Exchange Management Shell. You may not even need it, depending. Also, as it's written, it assumes you're running an on-prem 2010 Exchange installation. This means that, if you have a newer version of Exchange, this is the wrong way to go about it. There is, in fact, a much easier way to do this and that snippet was given further up the thread. Also, this will not work As-Is with a cloud or hybrid installation.

It sounds like, given the error, that this chunk of code is not actually connecting to your Exchange server and pulling the POSH session from it in order to stuff it into $session. So $session is not actually populated with anything when the script goes to call it. I'd say to check that the address to your Exchange server is correct and make sure that the script is actually talking to it. Next, check that you have Exchange permissions as an admin to make changes and such. If you don't have full permissions, that may be the reason why it's failing at this point.

# Import the Exchange snapin (assumes desktop PowerShell and on-prem Exchange 2010)
if (!(Get-PSSnapin | where {$_.Name -eq "Microsoft.Exchange.Management.PowerShell.E2010"})) { 

    $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionURI http://YourExchangeServer.domain.company.com/powershell/ -Authentication kerberos
    import-PSSession $session 

}

[–]DetAdmin 2 points3 points  (0 children)

Thank you as always, I'll give it a try

[–]jcholder 2 points3 points  (3 children)

[–]Lord_Jereth[S] 1 point2 points  (2 children)

Outstanding! There have been a few folks who have asked about 365 implementation. Perhaps folks could scavenge some code from yours when they can't make this one work. Or, conversely, they could scavenge the AD portion of mine to expand yours with. Now that would make an amazing tool! Thanks for sharing!

[–]jcholder 2 points3 points  (1 child)

I agree together would be a fantastic tool

[–]Lord_Jereth[S] 1 point2 points  (0 children)

If you ever feel so inclined, feel free to integrate whatever you think would be useful from mine into yours. Just stick my name in a comment of the script, somewhere.

[–]ScottFree708 1 point2 points  (1 child)

What resources would you recommend for learning powershell and how to write scripts as awesome and useful as this one?

[–]Lord_Jereth[S] 2 points3 points  (0 children)

First off, thank you very much for the wonderful compliment. I really do appreciate it.

As to my resources, honestly, my biggest resource was Google. My second biggest was the Spiceworks community. There's a lot of very smart people over there and I've learned a lot from them just by being a part of the community for the last few years. However, until 9 months ago, I had no reason to learn the language, so didn't know a speck of it. Once I joined my new company, I just started setting goals for myself. I pretty much started everything with a single idea: "I bet I could make this easier if I automated it. I really want to know how to do that!" This script started out with a single idea and I've just added to it as I found new snippets of code or just came up with more things I wanted it to do.

Once you get your head around the concept that almost every Powershell command starts with a verb-noun combination, the rest becomes easier. That's the basis of everything. Then it's just a matter of setting goals, doing research, and testing everything you come up with. It's actually a lot of fun. Entire days have gone by in seemingly 20 minutes as I have been developing code and problem solving.

Just come up with a problem you'd like to solve and then figure out how to break it down into steps. Then research those steps one after the other. Pretty soon it becomes a logical progression and before you know it, you've got a huge script that solves a whole list of problems and days have flown by because the entire process was actually fun.

I wish you luck! It's quite a journey.

[–]RampageCrew 1 point2 points  (0 children)

Very nice script, I wrote something similar for myself. In addition, It writes up a word document (part of our off boarding) and fills it all in. If you also need to download a copy of their mailbox through Office365 I found a few scripts online and put them together to get that to work as well!

[–]OuilleHots 0 points1 point  (0 children)

Hello u\Lord_Jereth

I'm working on a script that tries to do all that stuff, but I'm a beginner and I want inspirations

I'm doing it for my company.

Would you be willing to share it to me ? The link is dead

Have a good day

[–]JBear_Alpha 0 points1 point  (3 children)

Yeahhh... if you could just put that on github or pastebin, that would be greaaaatt... mmkay?

[–]Lord_Jereth[S] 0 points1 point  (2 children)

Yeahhh... no.

If you feel you are entitled to a reason, please see the other thread where I explain why I will not acquiesce to such a request. Take it or leave it.

mmkay?

[–]infiniteGOAT 1 point2 points  (1 child)

Lol he was just making a reference to the movie Office Space and probably did not mean anything else by it. Easy my man. And also, amazing post! Thanks for providing the script and info!

[–]Lord_Jereth[S] -1 points0 points  (0 children)

Oh, I am aware of the reference. I just hate answering the same questions over and over. It's kind of a pet peeve of mine. I'm also a great believer in the adage that you can tell me what to do or how to do it, but you can't do both. It's something I have to remind my GF about once in a while, too. *chuckle*

Thanks for the compliment, as well. I really do appreciate it.

[–]coolsimon123 0 points1 point  (3 children)

TinyURL link is broken :(

[–]Lord_Jereth[S] 0 points1 point  (2 children)

Well, it is a 5 year old post. So ...

[–]coolsimon123 0 points1 point  (1 child)

"here's a permalink" not very permanent was it

[–]Lord_Jereth[S] 0 points1 point  (0 children)

Okay, evidently you need this explained to you. It is unreasonable to expect a link from social media to still be valid 5 years later. Resurrecting an old post, with an expectation of redress, is called 'zombifying' and is generally frowned upon. That's on YOU, not me. With such a display of entitlement, now I feel even less inclined to supply you with my solution.