Importing User Photos to Office 365 in bulk for your company.

In a previous post, I showed how you could update one user’s photo for their Outlook and AD profiles via PowerShell. In this post, we will explore how to do this for your entire organization via PowerShell to Office365.

NOTE: I have not tested the scripts as I do not have enough mailboxes in my O365 tenant along with not using a ‘.’ in my alias. If the scripts are incorrect, please inform me with the correction and I will update accordingly.

Please make sure that your photos are reviewed before posting, and try to keep the file size of the photos to a minimum. In Office 365, there exists a limitation for the user photo not to be more than 10 KB in size, but I will show you how to get around that limitation.

Having a user photo for each of your users is very beneficial as it personalizes each account to a face in the company. The user photos can be viewed in below locations:

  • Outlook Web Access
  • Contact Card
  • Thumbnail in emails
  • Outlook Client
  • Yammer
  • Lync Client
  • SharePoint (People Search / Newsfeed)

Steps to take:

  1. Remove the 10KB photo size limitation in Exchange Online
  2. Prepare a folder with all users photos
  3. Update the profile photos via a PowerShell cmdlet.

Connect to Exchange Online with the RPS Proxy Method to remove the 10K size limitation

NOTE: In the PowerShell cmdlet above, we connected using a different proxy method. This was to overwrite the limitation of uploading the images with size more than 10KB. Using the different proxy method (/?proxyMethod=RPS ) to connect to Office 365 in the above cmdlet accomplishes this.

Prepare a folder locally and place all the photos in that folder

Create a folder named C:/UserPics and make the filename of each photo be the username of that particular user. (i.e. llingerfelt.png)
The below script should be able account for aliases that have a ‘.’ in the id as well. (i.e. lance.lingerfelt)

NOTE: From my research, there is no set photo type that is required for the photo. My suggestion would be to keep the photos .png for size constraints while maintaining picture clarity.

Update the profile pictures via PowerShell

Create the following script and name it Photos-Update.ps1

Run Photos-Update.ps1 and the script should upload the photos to Office 365 and apply each photo to the corresponding user.

NOTE: If you’re still having some issues with the alias having a ‘.’ in the name, you can also configure the Photos-Update.ps1 script in this manner to get that working properly:

HAPPY SCRIPTING!
PLEASE COMMENT!

store.ldlnet.net
LDLNET LLC! Your Source for Pofessional IT Services!
www.servermonkey.com
Contact ServerMonkey.com for your IT Hardware Needs!

REFERENCES:
How to import Office365 User photos over 10KB & without CSV in bulk

Issue with NAT on Cisco ASA

I was working on upgrading my ASA firewall and was running into an issue with internet working on my device, but none of my server services were responding to requests:

Result:
input-interface: outside
input-status: up
input-line-status: up
output-interface: inside
output-status: up
output-line-status: up
Action: drop
Drop-reason: (no-adjacency) No valid adjacency

I had configured 1-to-1 Object Based NAT translations for my servers for this purpose as had been configured on my prior ASA device. I had just copied the NAT rules to the new device thinking that it should just work. Needless to say, I had to call Cisco TAC and open a case. This seemed to be an issue for them as well. We kept getting the same error as above with another error listed during the NAT translation of the packets:

ifc selected is not same as preferred ifc
Doing route lookup again on ifc inside

We could ping internally to the server successfully from the ASA through the inside port:

LDLNET-FW01(config)# ping LDLNET-LAN 192.168.100.x
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.100.x, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/1 ms

Packet Capture:

4 packets captured
1: 01:01:21.086894 192.168.100.2 > 192.168.100.x: icmp: echo request
2: 01:01:21.087153 192.168.100.x > 192.168.100.2: icmp: echo reply
3: 01:01:21.087886 192.168.100.2 > 192.168.100.x: icmp: echo request
4: 01:01:21.088069 192.168.100.x > 192.168.100.2: icmp: echo reply

Again, I had created Object based NAT translations that should have worked for all the inside ports and allowed the packet traffic through properly:

object network Exchange_Server
nat (any,any) static ExchOut net-to-net

Not having knowledge what the net-to-net statement within the NAT Rule stood for, we ended up scrapping all of the Object based NAT rules and created a new rule using a static route:

nat (LDLNET-LAN,outside) source static Exchange_Server ExchOut description Exchange NAT Both Directions

Doing this worked for us and allowed traffic that was NOT translating correctly to be translated and flowing correctly through the ASA.

Phase: 17
Type: FLOW-CREATION
Subtype:
Result: ALLOW
Config:
Additional Information:
New flow created with id 12345, packet dispatched to next module
Module information for forward flow …
snp_fp_tracer_drop
snp_fp_inspect_ip_options
snp_fp_tcp_normalizer
snp_fp_translate
snp_fp_adjacency
snp_fp_fragment
snp_ifc_stat

Module information for reverse flow …
snp_fp_tracer_drop
snp_fp_inspect_ip_options
snp_fp_translate
snp_fp_tcp_normalizer
snp_fp_adjacency
snp_fp_fragment
snp_ifc_stat

Result:
input-interface: outside
input-status: up
input-line-status: up
output-interface: LDLNET-LAN
output-status: up
output-line-status: up
Action: allow

Great! This is working now! The only issue is that I had to create static rules that go through the single interface on the ASA. What if I need to connect other devices to the ASA on different interface ports? Well, I will have to create the static NAT rules for those ports as well. If the current interface fails, I will have to recreate the static NAT Rules for the interface port that I change to. Secure in a way, but not how I think it should be designed.

If anyone has any suggestions for the configuration of this, why I was getting the error, or a way to get the Object Based NAT rules working properly, PLEASE COMMENT!

I’M ALWAYS LOOKING FOR THE BEST SOLUTION!
PLEASE LEAVE YOUR COMMENTS!

LDLNET LLC (844) 884-7838
Contact sales@ldlnet.net for more information!

Set the profile pic for a single Exchange user via PowerShell

I wanted to update my picture within my Outlook profile and AD account really quickly without having to go through OWA to do so. I found this cmdlet that will allow for that picture to be changed very quickly via Exchange PowerShell.

NOTE: This can be done with On-Premises Exchange and Exchange Online PowerShell

Old picture within my account

First, download the picture you want to use to the computer that you want to run the cmdlet from. Also, make sure the picture is cropped and centered prior to running the cmdlet. I saved the pic to C:\temp for my scenario. The best format to use would be jpg. I named the file User1_Profile.jpg

Next, open Exchange PowerShell on the computer you saved the pic to and run the following cmdlet to change the photo:

Once completed, the Outlook client should be closed and reopen so that the new picture is visible in the profile.

Picture change completed

I will post how to perform this for multiple users for Exchange and Office365 in a later post.

REFERENCES:
Set User Photo with Exchange PowerShell

Purging Soft Deleted mailboxes from Exchange Server

If you’re a seasoned administrator, you have knowledge that in Exchange, the database settings will allow you to set the deleted mailbox retention. The default is 30 days, but sometimes you need to purge all those deleted mailboxes to do some ‘spring cleaning’ as it were. Note that doing these cmdlets does not change the ‘Whitespace’ of the database or the size. In my case, I had to purge everything of a toxic individual that was tainting my network much to my disappointment and did the following to complete that task.

The following cmdlet will seek all Soft Deleted mailboxes within the database you select and manually purge them from Exchange.

Now, should you only want to remove one mailbox, you will need to get the GUID of that Soft Deleted mailbox first so that you can enter it for the identity parameter.

You can also preform a similar task for a disabled mailbox:

You can perform the task on all disabled mailboxes for that database as well:

NOTE: I would be very careful when performing either of these cmdlets as they will completely purge the mailboxes from the schema. If these cmdlets assist you with your ‘spring cleaning’, I will have been happy to assist.

HAPPY PURGING!
PLEASE COMMENT!
IGNORANCE IS NOT BLISS!

References:
Purging Deleted Mailboxes on Exchange 2013

Server Monkey
LDLNET LLC’s Preferred Server Equipment Hardware Vendor

HTTP to HTTPS redirect for websites in IIS

I’ve been building this blog along with my consulting business and needed to secure my websites with SSL for BBB accreditation. That accreditation is still pending at this time, but I want to show good faith in business practices to attain that accreditation.

So, I purchased my certificate and preformed the following to assure that all traffic to my websites are SSL secured. There are a number of ways to do it, and even do it for Exchange, (which I will cover in another post), but I found a great article that is simple and will work for most standard web sites. The link will be at the bottom in the references section. 🙂

Redirect all HTTP traffic for your website to HTTPS

  • You will need to download the URL Rewrite Tool: Instructions HERE
  • Ensure that the IIS site you are using is configured for the proper port 80 binding. In this case we are listening for all traffic on port 80. But you could restrict this based on host header as needed
  • Next, once URL Rewrite is installed, create a new URL Rewrite Rule on the website that you want to make the change on:
Steps to create a new URL Rewrite Rule
  • Use the following steps exactly to create the redirection properly for your website:
  • Match URL Setting:
    • Name your rule (i.e. ‘http to https’)
    • Requested URL: ‘Matches the Pattern’
    • Using: ‘Wildcards’
    • Pattern: ‘*’
    • Ignore Case: ‘Checked’
  • Conditions Setting:
    • Click Add
    • Condition Input: ‘{HTTPS}’
    • Check if input string: ‘Matches the pattern’
    • Pattern: ‘off’
    • Ignore Case: ‘Checked’
  • Server Variables Setting:
    • No Settings Changed or Added
  • Action Setting:
    • Action Type: ‘Redirect’
    • Action Properties
      • Redirect URL: ‘https://{HTTP_HOST}{REQUEST_URI}’
      • Append Query String: ‘Checked’
      • Redirect Type: Found (302)

Note: In this example {HTTPS}, {HTTP_HOST}, and {REQUEST_URI} are all URL parts that can be accessed using the URL Rewrite module. More information on URL parts can be found here.

  • Apply the rule so that it is saved to IIS
  • Perform an IISRESET from an Administrative PowerShell Session or Command Prompt to Enable all the settings properly

Changes Made

The URL rewrite rules get written to the web.config file for the site you are working in. For example, the above configuration should result in this addition to the web.config file:

That should take of it all for you and now when users connect to your website via http, they will be automatically redirected to https SSL.

HAPPY CONFIGURING!
PLEASE COMMENT!

LDLNET - Banner
LDLNET LLC – Life In Action! Your Source for Professional IT Services!

References:
Creating Rewrite Rules for the URL Rewrite Module
URL Rewrite for IIS7 http to https redirection
URL Component Reference
Redirect from HTTP to HTTPS using the IIS URL Rewrite module

Customize your Outlook Web App Logon Page

As many of you are aware, Microsoft provides a default logon page for OWA, the Outlook Web App. Most companies, like myself want to be able to customize that page so that it suites your organization. Here is what my company OWA page looks like:

Customized OWA Logon Page

I have changed the color on the left to match my scheme, replaced the Outlook Logo with my company logo, and added a disclaimer to notify users. Below is the process to do that effectively for your organization.

NOTE: Every time you install an Exchange Cumulative Update (CU) or new version of Exchange Server these modified files will be replaced. Remember to backup your original and changed files to another folder so that you can replace them when you Update or Upgrade or if something goes wrong with the changes.

Customize the color of the Outlook on the web sign-in page

  • Use Notepad to open the file:

%ExchangeInstallPath%FrontEnd\HttpProxy\owa\auth\<ExchangeVersion>\themes\resources\logon.css

  • In the logon.css file, replace the default blue hexidecimal color value #0072c6 with the HTML RGB value that you want to use. You can use the following LINK to choose the color you wish to use.
  • When you’re finished, save and close the file.

Here are the different graphics that can be changed on the OWA logon page and their associated files:

Outlook on the Web sign-in page with element call-outs
ImageFile nameLocationDimensions (width x height in pixels)Bit depth

favicon.ico 
%ExchangeInstallPath%FrontEnd\HttpProxy\owa\auth\<ExchangeVersion>\themes\resources
16 x 16 
32 

olk_logo_white.png 
%ExchangeInstallPath%FrontEnd\HttpProxy\owa\auth\<ExchangeVersion>\themes\resources
128 x 108 
32 

owa_text_blue.png 
%ExchangeInstallPath%FrontEnd\HttpProxy\owa\auth\<ExchangeVersion>\themes\resources
300 x 76 
32 

Sign_in_arrow.png (for left-to-right languages) 
Sign_in_arrow_rtl.png (for right-to-left languages) 
%ExchangeInstallPath%FrontEnd\HttpProxy\owa\auth\<ExchangeVersion>\themes\resources
22 x 22 
32 
  • Just resize your images to the given dimensions in the table, rename them to the file name, and replace the files in the directory.

Change the disclaimer text for your OWA logon page

Next, we want to add a disclaimer to our logon page. To do that, we need to modify the logon.aspx document in the following directory:

%ExchangeInstallPath%FrontEnd\HttpProxy\owa\auth\logon.aspx

Open the file in Notepad or your favorite HTML editor and search for the text ‘hidden-submit’. When you find the text, you can add your disclaimer text under the div class=”disclaimer” tag as I did in the following example:

Save your logon.aspx file and give your OWA server an IISRESET for good measure. You should be good to logon with the new page from that point on.

HAPPY CONFIGURING!
PLEASE COMMENT!
THANKS FOR YOUR SUPPORT!

References:
Customize the Outlook on the web sign-in, language selection, and error pages in Exchange Server
CUSTOMIZE EXCHANGE 2016 OUTLOOK ON THE WEB SIGN IN PAGE
Customizing Exchange 2016 OWA

Unable to open settings from the Settings App in Windows Server 2016/2019

In Windows Server 2016/2019 you have been upgraded to the Windows 10 Desktop Experience GUI. So, in the new versions, you are directed to use the Gear Box in Windows to get to your settings. What was happening within the Settings is that I would choose a setting that calls on the control.exe file to open a Control Panel app. I would get the following error when attempting to do that function:

Permission Denied to Open a CPL Applet through control.exe

I immediately think it is a permissions issue. So I go to try to validate the permissions so that I could change them. Turns out, that due to it being a Windows System directory, I couldn’t modify the permissions without compromising directory security with NTFS permissions:

The options are all greyed out for the directory on purpose

Now, if I open Control Panel, Network Sharing Center, etc…, I was able to access the applets with no issues. This was just happening in the Settings Gear Box Application. So, I started looking around and found that there is a registry key that needs to be modified so that your Administrator account can open these settings apps through the Settings Application:

1) Launch the Registry Editor (regedit.exe)
2) Navigate to:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System

3) Change the value of FilterAdministratorToken (REG_DWORD) from 0 to 1 (If you don’t see that key, you can create it by right-clicking on any empty space from the right panel and select New > DWORD value, type the name and set the value to 1)
4) Reboot the computer and then it will be working fine.

I decided to create a Group Policy in AD to add this registry key so that it would propagate to all my 2016/2019 Servers:

1) Launch the Group Policy Manager
2) Create a new GPO and Link it to your Domain
3) Go to Computer Configuration > Preferences > Windows Settings > Registry > New Registry Key (DWORD)
4) Set the Action to “Replace”
5) Set the path as:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
6) Set the Key as FilterAdministratorToken
7) Set the Value as 1 (Decimal Format) and Save
8) Run gpupdate /force on your servers.
9) Schedule a Reboot of those servers for the change to truly take effect.

GPO Settings

After the reboot of the server, all the apps launched correctly from the Settings Application within Windows. I am going to research a little more to see why this is like that. If you have a comment, or more information, please feel free to post!

HAPPY TROUBLESHOOTING!
PLEASE COMMENT!

Installation of Exchange Server 2019 on Windows Server 2019

I have realized recently that I am an Exchange Messaging Professional, but yet, I have not posted the methodology of how I install an Exchange Server Mailbox Role. So here it is!

Install Windows Server 2019

Exchange Server 2019 requires Windows Server 2019 to run. For my environment, I haven’t necessarily need to follow all the enterprise level design aspects of database numbers to mailbox size ratios, number of servers, front/back end configurations, DAG Implementation, etc… If you want or need to delve into that realm, you can go here. I have need for a single server with only a few databases for a small number of mailboxes, so I am approaching it from that standpoint.

So first, in Hyper-V, I configured my VM with the following specifications:

Processors: 2 procs with 2 cores each – 4 Virtual Processors Total
RAM: 32GB with dynamic memory enabled optional
Drives: 2 .vhdx drives of 120GB each (OS / Exchange Data)
CD: Windows 2019 ISO
Default Settings for the rest of the VM Settings

Next I installed Windows Server 2019 Datacenter with the GUI! You can install it on Server Core if you wish. That information can be found in this link.

I ran through the setup of Windows and installed the OS on my first vhdx drive. I booted up, set the local admin password, and logged in. Once in Windows, I went to the Local Server Settings in Server Manager and configured the following settings:

Set the Date, Time, and Time Zone. (Once in the Domain, this would sync through Group Policy)
Set IE ESC to allow Administrators to have full IE access.
Set Remote Desktop Settings to gain RDP access. (This would be locked down with Group Policy as well once on the Domain)
Set the IP Settings to Static Settings. (DNS Servers, Gateway, WINS, etc…)
Join the server to the Active Directory Domain.
Reboot the VM Server.
Logon to your Domain.
Configure Windows Update Settings. (I have WSUS through Group Policy, this was configured automatically upon reboot)
Download and install all Windows Updates for the server. Then Reboot.
Open Disk Management and configure the secondary vhdx drive to be your Exchange Data Drive.
I configured the drive to be a mounted folder ‘C:\Exchange\Data’ rather than another drive letter as that seems to be the more accepted form of installation for the data drive these days. That is based on the multiple configurations that I have seen for Exchange through experience in Enterprise environments. Again, to each is own and depending on you design specifications, you might want to do that differently.

Next, we need to install the prerequisites for the Exchange Mailbox Server. I have always used practical365.com to get the PowerShell script to install the prerequisites, but couldn’t find the article this time. Great site though! Instead, I got the information and ran the following from an elevated PowerShell Session locally on the server:

As part of the prerequisites you will need to install the following packages onto the server as well:

UCMA Runtime Install
Visual C++ Redistributable Packages for Visual Studio 2013

Once completed, you can begin the install of Exchange. If this is your first Exchange 2019 Server in your Organization, then you will need to run the following to update the Forest, Schema, and Domain so that Exchange will install properly:

NOTE: If you run into Prerequisite issues with the installation due to a “pending reboot”, check out my blog post for information on remediation of that issue.

Now that the environment is prepared for Exchange, you can actually begin the installation. I wanted to make my default database and logs folder to be on the Exchange Data volume that I created, so I included those settings in the setup command. Please look at the reference to the setup.exe switches for more information on that. Here is the command:

Setup should go through the installation via the PowerShell window and complete successfully. Reboot the Exchange Server, then you can then logon to the Exchange Admin Center and begin the process of configuration of how you need to integrate the Mailbox Server into your Server Farm. That configuration is for a later post.

PLEASE CHECK BACK FOR UPDATES!
PLEASE COMMENT!

References:
UCMA Runtime Install
Visual C++ Redistributable Packages for Visual Studio 2013
Install Exchange Server 2019 on Windows Server 2019 Core
Exchange Server Design Planning
Use unattended mode in Exchange Setup
Practical365 on Exchange 2019

Hyper-V 2019 will NOT mount ISO from a network share.

Like most IT guys. They have a repository of their ISO images saved on a network share so that they can mount the ISO if needed on multiple machines. I recently switched to Hyper-V and have been having an issue with creating VMs and using my ISO from my network share to do so.
Hyper-V Manager available through RSAT doesn’t have an option to mount an ISO or capture a drive from a machine on which is running. Instead it gives you drives of the Hyper-V host, and that would of course require you to have an ISO or the disc itself present on the host. I didn’t want to do that. I would rather have my repository share available for that purpose to allow for all the drive space to be available on the Hyper-V host.

So, I would map a network drive with my ISOs. The mapping would succeed, but mapped drive (letter) will not be visible in Hyper-V manager when trying to mount an ISO. Okay, so next I tried mounting from UNC share directly, but that would also fail, with the message:
“‘VM’ failed to add device ‘Virtual CD/DVD Disk’” “User account does not have permission required to open attachment”.

hyperv1
Access Denied Error when trying to mount the ISO

It goes back to the constrained delegation requirement for the Hyper-V host accounts to be used to perform functions such as this. This has been a pain to say in the least, as I have also had issues with live migration with my machines not being clustered due to different hardware.

So, in researching, I found this blog post. It has helped me through this issue with mapping the shared folder with the ISOs.

The cause of the problem is that the Hyper-V is intended to run with VMM Library Server and to mount files from it, not any random share. To re-mediate this:

  • You need to assign full NTFS and share permissions to computer account of Hyper-V on a shared folder with ISO’s you want to mount.
  • In AD on the computer account of Hyper-V machine delegate specific service ‘cifs’ to the machine you want your ISO’s mounted from. Microsoft calls this constrained delegation.

Here is step by step procedure for the constrained delegation:

  1. Go to Active Directory Users and Computers
  2. Find the Hyper-V server computer account and open up its properties.
  3. Go to Delegation tab.
  4. Select Trust this computer for delegation to the specified services only radio button.
  5. Click the Add button.
  6. Click the Users or Computers… button.
  7. In the Add Services window, click Users or Computers and enter the computer account that will  act as a library server and click OK.
  8. Select the cifs Service Type and click OK.

The resulting setup should look something like this:

Constrained delegation
What the configuration should look like for constrained delegation

I added both the server that contained the ISO images and the server that I run my RSAT tools from just to be safe. I next rebooted the Hyper-V host (that is a requirement).
When the host rebooted, I was able to successfully create the VM.

Hopefully, this will also solve my issue with live migration between my hosts. I will have to test that again and will inform everyone here if that succeeds as well!

PLEASE COMMENT!
THANKS FOR READING!

References:
Hyper-V Server 2012 won’t mount ISO from a network share
Hyper-V authentication in Windows Server 2016 for managing remote Hyper-V servers through RSAT
Constrained Delegation

Exchange Setup Repeatedly Says ‘A Restart from a Previous Installation is Pending’

I have had this issue with EVERY upgrade that I have ever attempted for Exchange Server from 2013 through 2019 CU1. You go to run the setup program and during the prerequisite checks, setup stops. The error listed is:

A restart from a previous installation is pending. Please restart the system and rerun setup.

During the prerequisite checks, Exchange Setup looks in the registry at the following keys:

  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Updates\UpdateExeVolatile
  • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations

Nine times out of ten, a restart does NOT remediate this error. In order for setup to continue properly, you must do the following:

  • Open regedit: Start > Run > regedit.exe
  • Set the HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile key value to 0 or delete it if present. <– This one is usually NOT present.
  • Delete the HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations key.
  • Re-run Setup.

You should now be able to run setup and upgrade your Exchange Server.

PLEASE COMMENT!
HAPPY TROUBLESHOOTING!

References:
A Restart From Another Installation Is Pending
Exchange Setup Fails – A Restart From Another Installation Is Pending
Microsoft Document – A Restart From Another Installation Is Pending

Removing Hidden Devices in Device Manager

As you may have knowledge of, if you are reading my blog. I am currently migrating off of VMWare to Hyper-V. Now, as I convert my machines to Hyper-V, it uses a totally different driver for the Network Card. I am having to rebuild the NIC settings within windows to setup the NIC for the Hyper-V VM to get the machines on the network properly again. The VMWare NIC disables and hides the NIC from the VMWare driver in Device Manager.

What this does is make Windows think it has two active network cards, even though one is disabled and removed/hidden in device manager. So, to clean things within Windows, I have to perform the following procedure to remove the hidden device:

Open PowerShell as Administrator
Next, type the following cmdlet and press Enter:

Next, open Device Manager from the PowerShell Session:

When the Device Manager GUI opens, click the View menu
Click 
Show Hidden Devices
Go to the Device that is hidden, in my case the Network Adapter
Right-Click the Device and select Uninstall

Close the Device Manager GUI and PowerShell session

This cleaned the old hardware drivers off the system and allowed the current Hyper-V NIC to be the only one installed.

HAPPY TROUBLESHOOTING!
PLEASE COMMENT!

How to transfer FSMO Roles using PowerShell

A rare weekend post for me! HA! I am currently migrating my server environment from VMWare 6.7 to Server 2019 Hyper-V. I have a separate standalone box that I use for my VM backups and as a tertiary DC. Since I had to shut down my VMs in order to convert them, I needed to quickly move my FSMO roles from the DC Virtual Machine to the Standalone box so things would stay running.

I found this great article on how to do that quickly through PowerShell since it is a pain to go into ADUC, ADDT, and setup an MMC for the Schema snap-in.

When you create a domain, all FSMO roles assigned to the first domain controller in the forest by default. You can transfer FSMO roles from one DC to another both the Active Directory graphics snap-ins and the PowerShell command line. Moving FSMO roles using AD PowerShell has the following benefits:

  • You do not need to connect with a MMC snap-ins to the future role owner;
  • Transferring or seizing FSMO roles does not require a connection to the current or future role owner. You can run AD-PowerShell module cmdlets on a Windows Client or Server running RSAT Tools;
  • To seize the FSMO role (if the current owner is not available), it suffices to use an additional parameter -force.

Import the Active Directory Module Into PowerShell:

To get the current forest level FSMO role owners (Domain Naming Master and Schema Master roles) you can use the following PowerShell cmdlet:

To view domain-wide FSMO roles (Infrastructure Master, PDC Emulator and Relative Identifier Master roles):

Transfer FSMO Roles using PowerShell

To transfer FSMO roles between Active Directory domain controllers, we use the PowerShell cmdlet:
Move-ADDirectoryServerOperationMasterRole

To use the Move-ADDirectoryServerOperationMasterRole cmdlet, you must meet the following requirements:

  • There must be at least one DC with a version of Windows Server 2008 R2 or higher
  • PowerShell version 3.0 or newer
  • Active Directory module (2.0  or newer)

NOTE: Unlike the Ntdsutil.exe utility, the Move-ADDirectoryServerOperationMasteRole cmdlet can be performed from any domain computer to migrate the Operations Master roles if you have the appropriate rights (Domain admins and Enterprise Admins).

Import the AD Module:

I needed to move all the roles from one server to the other, so, I ran the following to do so:

NOTE: To simplify the command, you can replace the names of roles with numbers from 0 to 4. The correspondence of names and numbers is given in the table:

PDCEmulator0
RIDMaster1
InfrastructureMaster2
SchemaMaster3
DomainNamingMaster4

So, by having knowledge of these numbers, you can simplify your cmdlet:

NOTE: In the event that the current owner of one or all of the FSMO roles fails, the forced transfer of FSMO roles is performed by the same command, but with the -Force option. Also, after the FSMO roles have been seized, the domain controller from which the roles was seized should never be connected to the domain. You will need to preform a metadata cleanup of the Schema before even thinking about putting that failed server back into production.

Once completed, I ran the previous cmdlets of Get-ADForest and Get-ADDomain to verify that the FSMO roles moved to the destination server.

As of now, my conversion to Hyper-V is going smoothly, although it takes quite a bit of time to convert the hard disks. Thanks again!

HAPPY TROUBLESHOOTING! KEEP SCRIPTING!
PLEASE COMMENT!

Reference:
How To Transfer FSMO Roles Using PowerShell

Generate Automated E-Mail From Performance Counter Alert

Recently, I was trying to load this IT Blog and noticed that the page took a very long time to load properly. So, first thing I did was logon to my Web Server to check things and saw that the Performance was very slow, almost to a halt. When I was able to pull up Server Manager, I saw the following:

The Performance Alert was pegged at 99+ alerts. I went into the alerts for the performance and saw the following:

My CPU Usage was pegged at 100% for many hours. As I was having issues with the server and could not dig any deeper to find what was running to cause the error other the the w3wp process, I decided to reboot the server.
Rebooting did resolve the issue at hand, but I needed a better way to alert myself when the processor pegged at 95% or more over at least a steady two minute period. That way I could keep the websites going and restart the server if necessary due to an issue with a process pegging the CPU.

I don’t have SCCM or any robust alerting software like we have a my employer, but not to worry, Windows Server has a built in method to generate a task using Task Scheduler when the Performance Counter is above threshold for the time period that you set.

Step 1 – Create your PowerShell Script

The first thing that you need to do is write a Powershell script that when run can send an email. While researching this I discovered many ways to accomplish this task, feel free though to experiment and use what is right for your environment.

Here is an example of a Powershell script that when used in conjunction with Task Scheduler and Perfmon can send an email alert automatically when any user defined performance counter threshold condition is met. In my environment I set this to C:\PowerShell\AlertEMail.ps1

If you notice, this Powershell script takes four arguments and assigns them to variables used in the output. It also saves the computer name to a variable which is also used as part of the output. By doing this the script can be used to send an email on any Perfmon Alerting Counter and on any server without additional customization of the script.

Step 2 – Setup a Scheduled Task To Be Run

In Task Scheduler we are going to Create a new Task as show in the following screen shots.

Create Task

Give the Task a name, you will need to remember it for the next step. Make sure the task is run with an administrative account and is run whether the user is logged on or not.

There are no Triggers to setup here. This Task will actually be triggered through the Perfmon Counter Alert we will set up in Step 3.

On the Action tab you want to define a new action. The action will be to Start a Program and use the following inputs, please adjust for your specific environment.

Program/Script: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Add Arguments: -File C:\PowerShell\AlertEMail.ps1 $(Arg0)

Next, set your Conditions and Settings Tabs to the following settings as I did for this purpose. If need be, you might need to set them differently, but these settings should work just fine.

Step 3 – Create the Alert Trigger in Performance Monitor

Open Performance Monitor and Create a new Data Collector Set under Data Collector Sets > User Defined

Name the Alert (This one is for the Processor Usage)
Assign it as a Performance Counter Alert

I needed to monitor the Total % Processor Time for all processors on the server combined, so I set the counter to monitor from the available counters.

I then set the threshold to Alert when the processor is over 95% with Processor Time. I also let it run as the System account, and then saved the settings:

Once you have created the Data Collector Set go into the Properties of it and make sure the Alerting threshold and Sample Interval is set properly for each Performance Counter. Keep in mind, if you sample every 10 seconds then you should expect to receive an email every 10 seconds as long as the performance counter exceeds the threshold you set. I set my Sample Interval to 2 minutes so that if the percentage stays above 95% over that long of a time interval, I should take a look at the server and see what process is pegging the CPU:

If you select the Log an entry in the application event log don’t expect to see any entries in the normal Application event log. It will be written to the Microsoft-Windows-Diagnosis-PLA/Operational log in the Application and Services log directory.

Finally, we have to set an Alert Task that will trigger the Scheduled Task (AlertEMail) that we created in Step 2. You see that we also pass some of the Task arguments which are used by the PowerShell script to customize the email with the exact error condition associated with the Alert:

Once the Data Collector is configured properly you will want to start it.

If you configured everything correctly you should start receiving emails any time that alert threshold is surpassed. I also manually ran the script once from PowerShell with no Argument Data just to make sure the script would generate the email to my E-Mail Address.

Step 4 – Set the Data Collector Set to run upon server startup.

You now have one more step. Whenever you reboot a server the Perfmon Counter Alert will not start automatically. In order to survive a reboot you must run the following at a command prompt.

Note: “Processor Usage Alert” referenced in the script below is the name of my user defined Data Collector Set.

I now have a simple way to monitor my Web Server should this event happen again with the processor being pegged over a two minute period.

PLEASE COMMENT! I LOVE IMPROVEMENTS TO MY SCRIPTS! HAPPY TROUBLESHOOTING!

Reference:
Setup E-Mail Generation from a Performance Counter Alert

Killer Deal for a Standard Single Domain SSL Certificate – GoDaddy

I was in the market for renewing my VPN appliance SSL certificate and came across this great deal that I wanted to pass along. It gives you a new SSL Certificate for a single domain with basic validation for only $5.99 for the first year. I usually get a new certificate for my VPN appliance yearly so this works out great!

Promo Code for GoDaddy SSL Purchase

LINK HERE: https://www.godaddy.com/web-security/ssl-certificate

Just enter that code above when you are at checkout in the Promo Code field and you will get the certificate for $5.99! Great Deal. I am not sure how long this will last, so if you try it and it does not work, let me have knowledge of that and I will take this post down! Just remember to always look for these hidden gems when purchasing web related items like domains and certificates. You can always find deals if you look hard enough.

HAPPY TROUBLESHOOTING! HAPPY SAVING!

References:
GoDaddy SSL Certificate Coupons
TechSmart Info on GoDaddy SSL Certificate Promotion

Check Windows Updates Installed via PowerShell

I had an issue last night where a server lost Secure Channel Connection to the PDC Emulator (NETLOGON Event IDs 5719 and 5783). All tests to test the secure channel via PowerShell were failing. (i.e. nltest or Test-ComputerSecureChannel cmdlets) The server essentially needed to be rebooted. I had a dumb dumb in my brain and forgot to check to see if there were any pending Windows Updates, because those need to be installed at the proper time and to a schedule. So, when I ran the following command to reboot:

The Windows Updates were installed inadvertently which could have caused even more issues if they were NOT approved or caused another failure on the server. TO NOT DO THIS IN THE FUTURE, remember to run the following command to shut off the Windows Update Service BEFORE initiating the reboot of the server:

But, the deed was done. NOW, I had to find out quickly what updates WERE installed via PowerShell so that I could alert the proper folks and give them a heads up on possible issues. Luckily, the server did NOT have any issues and the initial problem with NETLOGON was resolved. Here is the command I ran to find out the installed hotfixes filtered by today’s date:

Here was the Output:

Caption=http://support.microsoft.com/?kbid=4480960 
CSName=DC01
Description=Security Update 
FixComments= 
HotFixID=KB4480960 
InstallDate= 
InstalledBy=NT AUTHORITY\SYSTEM 
InstalledOn=2/26/2019 
Name= 
ServicePackInEffect= 
Status= 

Caption=http://support.microsoft.com/?kbid=4480965 
CSName=DC01 
Description=Security Update 
FixComments= 
HotFixID=KB4480965 
InstallDate= 
InstalledBy=NT AUTHORITY\SYSTEM 
InstalledOn=2/26/2019 
Name= 
ServicePackInEffect= 
Status=
 

Since there were no issues, I was able to resolve the incident. I did notify the account team though of the inadvertent installation so that they could revert the changes if necessary.

Remember, troubleshooting to resolution is a methodical process, and when in an enterprise environment, you MUST be aware of all factors of change process, even when the resolution is a simple reboot of the affected server.

HAPPY TROUBLESHOOTING!
I LOVE COMMENTS! THANKS FOR READING!

References:
Methods of generating installed updates via PowerShell
Check Windows Update History via PowerShell
Disable or Bypass Windows Update Installation During Reboot/Shutdown of a Server

Website Availability Checker Script

We get alerts from time to time that SharePoint and Skype Websites might not be loading correctly or not at all. The following is a script that will generate a report, with time and date, showing the availability of the websites in question and the time it takes to load them.

First off, you want to create a text file called URLList.txt that will have the list of websites you want to check. I save the file in the C:\PowerShell directory but you can change the path to where you need it. If this happens often, having this list prepared will help you evaluate the environment quickly and allow you to troubleshoot if necessary efficiently.

URL List Text File

Here is the script:

Here is your output:

PowerShell Output
The report shown in your web browser

HAPPY TROUBLESHOOTING!
MAKE THIS SITE BETTER!
PLEASE COMMENT!

Reconnecting Shared Mailboxes after an O365 Migration

I get a lot of these incidents in my queue after a user has been migrated to O365. For whatever reason, most likely due to the mailbox being moved itself, whether it is the user’s mailbox, the shared mailbox, or both, the connections to the shared mailboxes stop working in Outlook and the user cannot connect to the shared mailbox.

Here is a quick and easy solution to use to disconnect and reconnect the shared mailbox(es) that you lose connectivity to when migrated. This is usually performed on Outlook 2016 and above as most users upgrade their client software when moved to O365.

First, we remove the existing shared mailbox connection:

  • Click the File > Account Settings > Account Settings.
  • Select your company email address in the account list.
  • Click Change > More Settings > Advanced tab > Select the Shared Mailbox > Remove
  • Click Apply > OK > Next > Finish.
  • The shared mailbox will now automatically be removed in your Folder pane in Outlook.

Second, we re-add the shared mailbox connection to Outlook:

  • Click the File > Account Settings > Account Settings.
  • Select your company email address in the account list.
  • Click Change > More Settings > Advanced tab > Add
  • Type the name of the shared mailbox in the window and click OK.
  • Click Apply > OK > Next > Finish.
  • The shared mailbox will now automatically be added to your Folder List pane within Outlook.

Note: The above procedure must be followed in order to properly reconnect the shared mailbox. You cannot remove and re-add the mailbox in the same process as that will not reset the connection properly. You must save the settings when disconnecting.

I hope that this will assist everyone when troubleshooting Outlook connectivity issues to shared mailboxes after a migration.

HAPPY TROUBLESHOOTING!
PLEASE COMMENT!

Moving mailboxes to O365 via PowerShell in Hybrid Configuration

As many of you have knowledge, I am studying for my MS-202 Exam. And, part of the knowledge needed is to be able to migrate mailboxes between on premises and Exchange Online through PowerShell. Here are the steps for the scenario to move a mailbox from on premises to O365:

1. Connect to Exchange Online via PowerShell

If you have read my previous post: Connect to All PowerShell Modules in O365 with one script
You should have all the settings needed to connect your PowerShell to O365. Note in this scenario, that all these cmdlets will be run from O365 PowerShell and will be monitored from O365 by either PowerShell or the Exchange Admin Center. You will not be able to monitor the moves from On-Premises.

2. Provide your on premises Migration Administrator credentials as a variable for your cmdlet.

3. Move a single mailbox.

In your hybrid configuration you should be doing directory sync with O365/Azure and the accounts should be available in the cloud showing that they are synced with AD. This also assumes that you have your MRS Proxy endpoint enabled, which can be done by the HCW. Also, make sure you have your licensing available for your mailboxes. From my knowledge, you can assign your license to the account in the cloud before moving, especially if you have a particular license that you need to assign the account. Other than that, moving the mailbox will assign an existing license that is available that includes an Exchange Online mailbox feature when the mailbox is moved.
Now we initiate the move with the cmdlet. Similar to what you would do in the GUI, this simple mailbox move cmdlet initiates the move request. It has most of the same parameters as a local move request including BadItemLimit, LargeItemLimit, AcceptLargeDataLoss, etc…
 
Use the following LINK for documentation on the New-MoveRequest cmdlet.

Now with all migration projects, we expect to have to move multiple mailboxes in a single batch. The following will show the process for moving mailboxes in bulk from on premises to O365:

1. Connect to Exchange Online via PowerShell

If you have read my previous post: Connect to All PowerShell Modules in O365 with one script
You should have all the settings needed to connect your PowerShell to O365. Note in this scenario, that all these cmdlets will be run from O365 PowerShell and will be monitored from O365 by either PowerShell or the Exchange Admin Center. You will not be able to monitor the moves from On-Premises.

2. Provide your on premises Migration Administrator credentials as a variable for your cmdlet.

3. Move multiple mailboxes in a single batch.

In your hybrid configuration you should be doing directory sync with O365/Azure and the accounts should be available in the cloud showing that they are synced with AD. This also assumes that you have your MRS Proxy endpoint enabled, which can be done by the HCW. Also, make sure you have your licensing available for your mailboxes. From my knowledge, you can assign your license to the account in the cloud before moving, especially if you have a particular license that you need to assign the account. Other than that, moving the mailbox will assign an existing license that is available that includes an Exchange Online mailbox feature when the mailbox is moved.

This time you want to create a CSV file using the alias or emailaddress as your header and then list the appropriate value for all the users in your batch group. Save the file locally as MigrationBatch01.csv or a name of your choice.

Use EMailAddress
 OR
 Alias as the header

Next you initiate the mailbox moves. When specifying the mailbox identity in the cmdlet, use the respective header in your variable declaration (either $user.EMailAddress OR $user.Alias)

Use the following LINK for documentation on the New-MoveRequest cmdlet.

GOOD LUCK WITH YOUR MIGRATIONS!
HAPPY TROUBLESHOOTING!

References:
Moving Individual Mailboxes to O365
Move Mailboxes in Bulk to O365
PowerShell Mailbox Migration to O365
Connect to all PowerShell Modules in O365 with one script
New-MoveRequest Microsoft Document

Customize your Default PowerShell CLI Prompt

We all like to have our customization in our Windows Desktop. Custom colors, icons, wallpaper, etc.. Well IT guy/gal, why not have your PowerShell CLI the same way? I’ve looked around at a few blogs and got some ideas to share with you on customizing your PowerShell CLI.

Now, by default, Windows looks in the following directory for your customization file:

C:\Users\(username)\Documents\WindowsPowerShell

It looks for a file called profile.ps1 and will load that script every time you load PowerShell once it is customized.

You can construct the script within PowerShell ISE or your favorite editor. The following is how I programmed the script to customize my PowerShell prompt:

First, we want to clear the slate on the PowerShell CLI. 
I like to add my contact information for instance.

Second, I run a script that I came across and added to my customization.
It get’s me the weather for the local area that I am from. Click the link for details.

How To Uniquify Your PowerShell Console (Scroll to Getting the Weather)

Next, I customize the PowerShell Window Settings so that it is the size and shape that I want.
I set the Directory Location, The Colors, and The Window Sizes.

Next, I wanted to write some text in the window before I get my PowerShell Prompt.
I work at Avanade, so I wanted to put a welcome message, today’s date, and what PS version I was running just because I could.

Lastly, we actually configure the prompt. There is a lot of ways to do this and I will leave references for you at the bottom of this post so that you can get more details on the commands actually run.
I wanted to have a colorful prompt that stated the company motto and put the current time.
I also configured the Window Title at the top to show text, the current user, and the current directory with different colors as that is my expressive part of my brain. 🙂

Here is the script in its entirety:

Here is the final product when opening PowerShell:

Avanade Custom PowerShell Prompt
My Customized PS Prompt

HAPPY SCRIPTING!
HAPPY VALENTINES DAY!

References:
Customizing your PowerShell Profile
Get-Weather.ps1
Modify your PowerShell Prompt
PowerShell Basics: Console Configuration