A Manager’s Guide to Working Remote

Image by Free-Photos from Pixabay

Co-authored by several managers with many years of working remote, and successfully managing teams across the country

Things to consider & general tips

Dress Code  

Working from home is different from working in an office, and leaders must be considerate. While many leaders of remote teams are not overly concerned with associates’ appearance or dress, sometimes it helps ease the transition to maintain an office-like dress-code. You may remind associates to consider the audience for meetings when considering their attire. Sweatshirts and caps to cover messy hair may be fine for a quick call with a teammate, but a video conference with a senior leader may bring the expectation of a more office-ready appearance.

Meetings

If at all possible, require associates to join meetings via video, and set that expectation in your meeting agenda. That being said, sometimes technical limitations necessitate audio-only (especially if multiple family members are using the same internet connection).

Be respectful if someone chooses to keep their video off for impromptu calls, meetings scheduled during typical meal times or late in the day. With these exceptional circumstances of working alongside childcare duties associates may sometimes be multitasking just to keep the family functioning. 

Workspace

If at all possible associates should try to have a dedicated work space at home. With everyone working and taking classes from home this may be challenging and leaders should be considerate.

Photo by Jay Wennington on Unsplash

Work Life Balance

Encourage your team to maintain a normal workday. Log in around the same time they would normally get into the office. Log off and close the laptop at the end of the day and maintain healthy boundaries. When working remote, it’s very easy to get burnt out from being close to work all the time.

Mental Breaks

Just as they’d get up to go get a coffee with a teammate while in the office, encourage them to take a few minutes for “work pace breaks” to walk the dog or check in with their spouse/kids now and then. It’s easy to pull inward and stare at the laptop for 8 or 9 hours without stopping. Set an example by telling the group that you’re going to take a walk, or stepping away for a mental break.

Compassion and Leading Your Team

While work-from-home is becoming more normalized in general, right now is not a normal work-from-home situation. Entire families are home and extra consideration should be shown to your team.

Adapt and Learn

Stay positive and engaged. Not only is this a change for your associates, it’s a change for you as a leader. Adjusting how your team works is a process, so don’t be afraid to try different things. 

What your team is experiencing 

Stress and Anxiety

Those of us who have been working remotely for years are not experiencing much change from our normal day to day, but associates who are new to working from home are experiencing quite a bit of anxiety. Switching to remote work is, by itself, a huge change, but to do it under the stress of a pandemic will affect productivity. 

Disconnection

Associates will definitely feel more isolated, sometimes going for hours at a time without seeing or communicating with another person. In addition to a Teams Channel, Google Group, or Slack room for work related conversations, create a space for your team to have “water cooler” discussions. We creatively call ours the “Water Cooler” and share funny pictures, interesting links and tell stories about our families. Lead by example and participate in these threads!

Disruption

A disruption in established work processes. There are more distractions at home, and equipment may be different. For example, the lack of a printer may change how someone reviews documents. Children demanding attention can turn a five minute task into 15 minutes. 

Communication hesitancy

Communicate frequently to associates and let them know how they should reach out to you (do you prefer IMs, emails, texts?) or if you will be unavailable during certain times. Reassure associates that you are available and open to converse just as if you were in an office. 

What to watch out for

Isolation

Make a point to check in with your associates regularly throughout the day, NOT as check-ins to see if they’re working, but rather check-ins to see how they’re doing mentally and emotionally. Be sensitive to anxiety or negative attitudes during the adjustment period. 

Trust

This is a good time to build trust as your associates figure out their new work rhythm. Do not spend your day trying to track everyone. Associates who are appreciated and trusted are higher performers. If you need to correct actions, be diplomatic and make sure you are communicating your expectations. 

Inclusion 

Virtual meetings can make it difficult for people to share opinions. Pause frequently to allow time for unmuting and interjections. Encourage the use of meeting chat for associates to share their thoughts. 

Set the first home page tab while keeping existing tabs in Google Chrome via PowerShell

Getting started:  Example Script (Zip), Example Script (preview)
Related article(s):  Set the first home page tab while keeping existing tabs in Microsoft IE

As a continuation of our post on IE, I’ll outline the steps we go through in the body of the example script provided.  In case you haven’t read through the IE tabs post, let me set the stage for the scenario we will walk through:

Consider a portal project roll out requirement stating the following requirements:

– You need to set the default home page tab for the supported browser(s).

This sounds easy enough.

– In doing so you need to ensure the preferred URL is always the first tab.

Yeah, ok.  That’s doable, and not terribly difficult.

– In doing so you need to keep any existing tabs that the user already has that

Ooohhh now we’re getting tricky.  Still, we’ve tackled that before.

– In doing so you need to know that, we support Chrome as a default browser here but do not have Chrome policy management implemented.

. . . Crickets . . .

Ummm, alright …

Now in the past this could be tackled with registry manipulation for both IE and Chrome.  However, with modern Chrome clients, the default tabs along with MANY other browser settings are tracked in a different location.  Most of the settings for a locally managed client (or rather, not managed by policy) have been relocated to a set of files in Chrome’s associated AppData folder.  The file that we will be manipulating is located here:

“%LOCALAPPDATA%\Google\Chrome\User Data\Default\Preferences”

If you were to open this file you will see that it is a JSON like data structure with lots of bits and bobs from the Chrome settings page all tracked in the file:

image

The method we will use to implement these settings is a PowerShell script which can be incorporated to login script or manually run.  To summarize the process I’ll outline it here and we can follow the steps along as we go:

1.  Start (with URL variable)
2.  Gather existing tabs to array variable for enumeration
3.  Build the variable string to replace with
4.  Replace with New tabs variable in the settings file

Let’s examine the script now.

Step 1: Start the script:
Similarly to our IE script, we need to initialize the script run with the a variable containing the new default home page tab’s URL.  Our example script does that with via a parameter and as you can see here is set with an initial default value:

#'http://www.perpetualreality.com/blog/2019/03/29/set-the-first-ho…-in-microsoft-ie/'
#region Establish Script Parameters
    PARAM(
        [Parameter(Position=0, Mandatory=$false)]
        [System.String]
        $global:newRootURL = 'https://wp.me/pawO3b-1x'
    );
#endregion

If you prefer not to use a parameter in your script, that’s fine too.  You can see that (because the new URL is actually required) the example also provides a way to set the static variable too:

if( !($global:newRootURL) -or ($global:newRootURL -eq '')) { $global:newRootURL = 'http://www.perpetualreality.com/blog' };

Step 2: Gather existing tabs for enumeration:
Next we need to read in the existing tabs so that we are able to iterate through them as we apply them back to the user’s ancillary tabs (after the default home page).

$chromePrefPath = ($env:LOCALAPPDATA + "\Google\Chrome\User Data\Default\")
$cDefaultPrefsPath = ($chromePrefPath + "Preferences");
$cPrefs = Get-Content -Raw -Path $cDefaultPrefsPath | ConvertFrom-Json;

You will notice here that we are collecting the entire file into an enumerable array type using the ConvertFrom-JSON cmdlet.  As mentioned before the Preferences file is stored in a minimized JSON data structure and this cmdlet can parse it for us to easily traverse to the existing tabs entries when running the logic to determine what tabs go where.

Step 3. Build the variable string to replace with
This step was a bit tricky to figure out.  ne would think that since we easily read the Preferences file into PowerShell with a ConvertFrom-JSON cmdlet, we could just as easily manipulate the data and output to the file with a ConvertTo-JSON.

NOPE!

Since we can’t do that, we will revert to old school string replacement.  But first, we need to build both strings, the string we are replacing, and the string we are replacing it with. Here are the primers:

$stringToReplace = '"startup_urls":[';
$replacementString = '"startup_urls":[';

Then iterate through each URL from the Preferences file ‘startup_URLs’ section.

if( $cPrefs.session.startup_urls.count -gt 0 ){
    $global:newSecondariesArr = @($global:newRootURL);
    $cPrefs.session.startup_urls | %{ 
        $secondaryURL = $_;
        addSecondary $secondaryURL $global:newRootURL; 
        $stringToReplace = $stringToReplace + '"' + $secondaryURL + '",'
    }    
} else {
#    Write-Host "No Ancillary URLs found";
}

You may notice here, that while iterating through the collection of URLs, we also call another function ‘addSecondary’.  This function’s purpose is to collect the URLs that may already exist and are not the URL designated for the primary tab.

            function addSecondary($secVal, $newRootVal){
                if( 
                    #Existing string not equal www.perpetualreality.com/
                    ($secVal.ToLower() -ne $newRootVal.ToLower()) -and ($secVal.ToLower() -ne ($newRootVal + '/').ToLower()) -and 

                    #Existing string not equal http://www.perpetualreality.com or http://www.perpetualreality.com/
                    ($secVal.ToLower() -ne ('http://' + $newRootVal).ToLower() ) -and ($secVal.ToLower() -ne ('http://' + $newRootVal + '/').ToLower() ) -and

                    #Existing string not equal https://www.perpetualreality.com or https://www.perpetualreality.com/
                    ($secVal.ToLower() -ne ('https://' + $newRootVal).ToLower() ) -and ($secVal.ToLower() -ne ('https://' + $newRootVal + '/').ToLower() ) -and

                    #Because deep down we are all SharePoint people
                    ($secVal.ToLower() -ne ($newRootVal + 'pages/default.aspx').ToLower() )
                ){
                    $global:newSecondariesArr += ($secVal);
                }
            }

Now that we have the sites added to our string to be replaced, we need to append these collected sites into the string that we are replacing  with.

$global:newSecondariesArr |% {
    $replacementString = $replacementString + '"' + $_ + '",'
}

And then close out the string syntax for both variables..

$stringToReplace = $stringToReplace.TrimEnd(',') + "]";
$replacementString = $replacementString.TrimEnd(',') + "]";

Finally, we do the replacement of the strings in the Preferences file:

(Get-Content (Join-Path $chromePrefPath $renamedPrefsFile) ).replace($stringToReplace, $replacementString) | Set-Content $cDefaultPrefsPath

As mentioned on our corresponding post: Set the first home page tab while keeping existing tabs in Microsoft IE, your use case and mileage may vary.  For the use case outlined above, our recommended best practice for implementation was to set this script to run at every login via GPO (in tandem with the IE logic if also required).

Hopefully this blog post has helped to show you how to easily set the first Chrome homepage tab while keeping your users’ existing tabs via script.  Download our f and give it a go yourself!

Set the first home page tab while keeping existing tabs in Microsoft IE

Getting started:  Example Script (Zip), Example Script (preview)
Related article(s):  Set the first home page tab while keeping existing tabs in Google Chrome via PowerShell

We often engage in SharePoint or Web App portal projects where the roll out phase may include a requirement to set the default home page tab for the supported browser(s).  While there are many ways to accomplish this for an enterprise, one use case that keeps cropping up at my clients in recent years is as follows:

  1. Set the first tab when the user opens their browser
  2. Set the first tab when the user Hits the home button
  3. Set the (rest of the) user’s existing favorite tabs when they open the browser or hit their home button

The first time I got these requirements I thought:

        1. This is easy to do with group policy or registry
        2. This is easy to do with group policy or registry
        3. Hmm, maybe, let me research and enlist help … fast forward

AHA! That’s not so hard for a one off request after all !

The next two times that #3 came up, I thought:

Ahh CRAP!  I forgot how to do this. 

So here we are writing this down for everyone’s benefit and save future brain damage. 

Because we primarily work in the Windows client space, PowerShell was the chosen tool to accomplish this.  There are many examples out there using scripted methods to address the first two requirements which serve as a great starting point. 

Our example script tackles the requirements above as follows:

Firstly we need to setup the variable for our new URL that will take over the primary tab.  You can see that the example script can take this as a parameter.  While the parameter is not required you can set a default value here as well ( the example is set to this post’s URL by default):

#'http://www.perpetualreality.com/blog/2019/03/29/set-the-first-ho…-in-microsoft-ie/'
#region Establish Script Parameters
    PARAM(
        [Parameter(Position=0, Mandatory=$false)]
        [System.String]
        $global:newRootURL = 'https://wp.me/pawO3b-1x'
    );
#endregion

If you prefer not to use a parameter in your script, that’s fine too.  You can see that (because the new URL is actually required) the example also provides a way to set the static variable too:

if( !($global:newRootURL) -or ($global:newRootURL -eq '')) { $global:newRootURL = 'http://www.perpetualreality.com/blog' };

Great, now that we have the new URL available, we need to tell the script where to put it.  For IE (and used to be Chrome, but not any more) that is a simple registry path:

$regPath = 'HKCU:\Software\Microsoft\Internet Explorer\Main\'

Now, because our detailed requirements dictate that we need to keep the existing tabs a user may have set in their IE options, we need a place to collect those as well.  Here we setup a quick array to handle them:

$global:newSecondariesArr = @();

Here we start by gathering what they have configured as the current first tab:

#Get current root tab URL for IE as string
$primaryTabKeyName = 'start page'
(Get-Itemproperty -Path $regPath -Name $primaryTabKeyName).$primaryTabKeyName | %{ 
    addSecondary $_ $global:newRootURL; 
}

Then collect any others they’ve set:

#Get current secondary tab URLs for IE as string array
$secondaryTabKeyName = 'Secondary Start Pages'
(Get-Itemproperty -Path $regPath -Name $secondaryTabKeyName).$secondaryTabKeyName | %{ 
    addSecondary $_ $global:newRootURL; 
}

You’ll notice in both steps to gather their primary and ancillary tabs above that we call on a function ‘addSecondary’.  While some fancy regex wizardry can accomplish the same in a single line of script, this example function uses some string concatenation to illustrate various string comparisons you may want to take into account. 

Remember, the goal is to validate that the URL being set doesn’t already exist in their tabs and thus won’t get duplicated into the ancillary tabs:

function addSecondary($secVal, $newRootVal){
    if( 
        #Existing string not equal www.perpetualreality.com/
        ($secVal.ToLower() -ne $newRootVal.ToLower()) -and ($secVal.ToLower() -ne ($newRootVal + '/').ToLower()) -and 

        #Existing string not equal http://www.perpetualreality.com or http://www.perpetualreality.com/
        ($secVal.ToLower() -ne ('http://' + $newRootVal).ToLower() ) -and ($secVal.ToLower() -ne ('http://' + $newRootVal + '/').ToLower() ) -and

        #Existing string not equal https://www.perpetualreality.com or https://www.perpetualreality.com/
        ($secVal.ToLower() -ne ('https://' + $newRootVal).ToLower() ) -and ($secVal.ToLower() -ne ('https://' + $newRootVal + '/').ToLower() ) -and

        #Because deep down we are all SharePoint people
        ($secVal.ToLower() -ne ($newRootVal + 'pages/default.aspx').ToLower() )
    ){
        $global:newSecondariesArr += ($secVal);
    }
}

As offered by many bloggers before me, the primary tab is easy for IE and just directly set to registry key:

#Set root tab URL for IE
Set-Itemproperty -Path $regPath -Name $primaryTabKeyName -Value $global:newRootURL

Now that we have collected and compared all the existing tabs, we can add all the URLs to the registry in the right order. With another easy registry key each of the remaining tabs can be set directly to the array:

#Set secondary tab URLs for IE
Set-Itemproperty -Path $regPath -Name $secondaryTabKeyName -Value $global:newSecondariesArr

Tada!

Or … well, wait … We don’t want everyone to have to run this manually right?   Your use case and mileage may vary, but for the use case I outlined above, the recommended best practice for implementation from here was to set this script to run at every login via GPO. We’ve also seen it setup for run once, kiosk, and manual needs.  As stated, our use case may vary.  

Hopefully this blog post has helped to show you how to easily set the first IE homepage tab while keeping your users’ existing tab via a simple script to meet your enterprise use case.  You may also be interested in our post to tackle one way to accomplish this with PowerShell for the Chrome browser too.

Happy scripting everyone!

Using SharePoint Search to boost your PowerShell powers

Getting started:  Example Script (Zip), Example Script (preview), SharePoint Search Query Tool (optional, but handy)

Have you ever needed to get some information from one or more of your SharePoint environments to analyze or inspect information from them? That may seem daunting or painful to aggregate, especially in bulk,  but SharePoint search can be your best friend in these instances.  This blog post will dissect the following example script to show you one possible way you can take advantage of this powerful pairing.

Since SharePoint search can be targeted to crawl/index many SharePoint environments as content sources, it natively does much of the content aggregation and correlation ‘hard work’.  Thus, providing you with SharePoint content catalogued by the known metadata attributes it understands of each object.

Hmmm.  Now to the tricky part.  How can I ask SharePoint Search for this catalogued information via PowerShell?

Enter, the SharePoint Search API: /_api/search/

First, we need to establish something called a Form Digest Request token.  I won’t go too far into what this is, but you can effectively consider it an authorization token the API uses to recognize your session is valid from a starting URL.

We accomplish this with a pair of functions, one to post a request for SharePoint asking the API for a token:

Post-RESTRequest ($endpoint, $postFormDigest, $body, $credential)

And another to call the post function and process the results:

Get-SPRESTFormDigest($xreqURL)

This is stored to a variable for use when asking the API for information:

$formDig = Get-SPRESTFormDigest($global:spAdminSite)

Now, with the Form Request Digest key in hand, we can talk to the Search API … but what should we ask it for?  How should we shape the request?

For the purposes of this discussion, we would like to ask SharePoint Search for a listing of all known SharePoint sites (and webs), including some known metadata: the path, type of site object, name, guid, size, site guid, and it’s SharePoint version.  Whew! Now you might see how this could be daunting; asking multiple environments for all of this to then aggregate together.

Fortunately, SharePoint search will have all of this information (and much more) for everything indexed in it’s content source.  We just have to ‘politely’ ask search for the the information using the correct syntax in order for it to return the pre-aggregated data for us to use.

Essentially the restful request structure we are going to ask for would compound as follows:

$global:spAdminSite +"/_api/search/query?querytext='*'&startrow=" + $rowNum + "&rowlimit=1000&selectproperties='Path%2cSiteName%2cTitle'&refinementfilters='contentclass:or(`"STS_Site`",`"STS_Web`")'&sortlist='Path:descending'"

::wiping sweat from brow::

That’s a bit ugly, IMHO! Let’s break that down into the pieces we wanted to ask search for, starting from blank:

$queryBuildBits = ""

Then we’ll add the location of the API (noting that the adminSite is arbitrary but you must be able to authenticate to it):

#region where to query?
$queryBuildBits += $global:spAdminSite +"/_api/search/query"
#endregion

Next, let’s tell the API information we’d like to ask for, this query parameter is synonymous with the search box on a search page. In our example we want all of them so we’ll use a wildcard as shown here:

#region what to look for?
$queryBuildBits += "?querytext='*'"
#endregion

Now, I’ll inject an assumption that we have MANY sites to ask Search about.  In that case, we need to account for the fact that search will only return so many results at once.  Due to this we need to request and collect the returned results in batches.  Here, $rowNum would start at 1, and our logic will increase that for the next batch if, as we process the return(s), the number of results is what we’ve specified.  We can specify how many to return per batch from Search (to then measure), as follows:

#region where to start and how many?
$rowsToRet = 350
$queryBuildBits += "&startrow=" + $rowNum + "&rowlimit=" + $rowsToRet
#endregion

Next, if you recall, we want to specify the metadata attributes we care about.  That is done with the &selectproperties= portion of the API call.  First we build an array of the properties we want($retProps), then enumerate the array to add them to our request string, and finally close out the properties with a graceful string addition (Title including the ):

#region what to return? 
$retProps = @('Path','SiteName','WebID','contentclass','Size','SiteID','SPVersion')

$queryBuildBits += "&selectproperties='"
$retProps | %{
    $queryBuildBits += ($_ + ",");
}

$queryBuildBits += ",Title'";
#endregion

So far, this would still give me any kind of result that SharePoint Search knew of.  However, we only wanted to ask search for the metadata as it pertained to Sites (and webs).  To narrow the results we can use a refiner and append it to our query string as show here:

#region refine your results?
$queryBuildBits += "&refinementfilters='contentclass:or(`"STS_Site`",`"STS_Web`")'"
#endregion

OK.  Who’s ready to talk to Search?  I know I am.  With my query string all put together, and my Form Digest Key in hand, we can submit a RESTFul query to the API via a third function I’ve provided in the script:

Get-RESTRequest ($endpoint, $getFormDigest, $body, $credential )

As with most RESTful SharePoint APIs, this will return a bulk of JSON including ranking information, metrics, etc. To inspect all of this, simply make the call to the API:

(Get-RESTRequest $queryBuildBits $formDig)

BUT, we specifically want the returned results for our requested query, so we can gather that from the data tree as follows:

$srchRes = (Get-RESTRequest $queryBuildBits $formDig).d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results.SyncRoot

SWEET!!!!! By now, you should have the first set of results!  If you have less than the number of sites you specified above, you are done and can process the data accordingly.  If you happen to have more than the number specified for your batch return you will need to gather these results and then submit your request for the next batch of results.

To do so, firstly we gather each of this batch to a collection. Note, I won’t go into the performance benefits in this post, but I tend to deal in exceptionally large data structures that use .NET queues as seen in this example.  You can use whatever hash/array structure you are comfortable with.

if( ($srchRes -ne $null) -and 
    ($srchRes.SyncRoot.Count -gt 0)
){
  $srchRes.SyncRoot | %{
      $global:qSPSiteURLs.Enqueue($_)
  }
}

Now that we’ve gathered this batch of results to our collection, we can increment our starting row variable, then repeat the Search API call again with the adjusted starting location.

if( ($srchRes.SyncRoot.count -eq $rowsToRet)
){
    $rowNum = $rowNum + $rowsToRet
}
else{
    $rowNum = 0
}

You might be asking how to kick the next request off.  In the example script provided, all of this is wrapped in a while that triggers on our $rowNum variable

while ($rowNum -ne 0){
    #put all logic in here 
}

To summarize, this example has illustrated a method that has saved me countless hours and tremendous amounts of brain damage when trying to stitch together large datasets from multiple farms + online.  I hope this helps to get you started thinking about how to leverage the SharePoint Search platform to do much of the ‘hard work’ in the collection and aggregation of typed objects throughout your entire content footprint.

Finding Your Path as an IT Pro

Until recently, career paths for IT Professionals seemed well defined, straightforward, and advancement was more or less linear. After choosing an area of interest, technical languages and roles became apparent. Staying on the same path throughout your career was the norm.  However, times have changed and to be successful we must adapt. The pace of change is rapid and employers need professionals who can learn new skills quickly – there is no longer a straight-line career path. After mastering one skill we must move on to the latest release as quickly as possible, constantly looking ahead to what skills are needed next. 

My personal path

I earned my BA in Liberal Arts at a world-renowned engineering school and my major was in Theater. Not knowing exactly what career I wanted to pursue, I decided to earn an MBA with a focus on Marketing. Fast-forwarding a few years, I found myself working in a business role with one of the nation’s largest IT recruiting and staffing firms – but I still was not on a defined career path.  Surrounded by IT recruiters, I discovered some common themes in the candidates that were chosen for placement – they were searching for people who were creative, could adapt quickly, and were eager to take on whatever challenges the client needed assistance with.  These abilities are crucial for success in addition to typical traits such as communication skills, integrity, and knowledge.  

I knew my talents were underutilized and soon an opportunity presented itself. A contract position that seemed to be a close match to my skills opened, and I went for it. Unfortunately, I only lasted one month. It was a terrible fit, and looking back I should have voiced my concerns right away. Armed with new lessons learned, a few months later I was placed on a highly technical team I was certainly underprepared for. My recruiter reassured me, she saw something in my ability to learn, listen and be creative. She was right…I flourished and within the span of a year was on my way to leading the team.

Failing is necessary

Even though I failed the first time I persisted and branched out, making that mistake was crucial to my career growth. If you succeed at everything you attempt, try something that makes you uncomfortable and forces you to grow as a person. Making mistakes forced me to evaluate my path and re-adjust as needed. I learned not everyone has the same way to get from point A to B. For my path, I thought about what I could offer my company, what processes I could improve or impact. I strived to offer a solution when identifying a problem, and started many of my own projects – which gave me more leadership skills, as well as bolstered my project management.

Being interested in a project but not having the skills required for the team can be another opportunity for growth. Take a chance and get involved any way you can, even if it’s just to observe. Many times, just asking can give you a lead for a future opportunity. It’s even better if the project is fun or has high visibility to elevate your professional profile. To keep your path manageable, try to balance challenges with easy wins so your career doesn’t totally derail. Don’t try to prove too much at once.

You are enough

The IT Pro can sometimes be categorized as the “Jack or Jane of all trades”. Don’t be afraid to narrow your focus if you choose! To find the right path, it’s ideal to try on as many hats as possible, what you excel at will reveal itself. Being a consultant allows you to work short contracts, building on your skills and strengthening the foundation to your career. IT Pros can see the big picture, we’ve experienced numerous situations and aren’t afraid to say, “I’m not sure, let me research and I’ll get back to you.” These skills come in handy when you need to communicate with anyone from executives to the average end user, and for advancing in your career. Remember that your unique characteristics are strengths so use them to relate to your colleagues and connect with your end users.

Despite being an IT Pro with impressive technical abilities, admitting you don’t know everything goes a long way with establishing trust with business partners. Speak up and ask the questions. A big part of asking questions and learning from others is to actively listen, learn, and be humble. We all start somewhere as the newbie in the room, and we learn continuously on our path. Fostering other’s professional growth is an important part of the tech community.  

What’s next

If you’re unsure what path to start with, or really can’t afford to make mistakes in your position, search online in tech communities or to find local user groups to make connections. See what other IT Pros are doing. The Microsoft Tech Community is an incredible source of contacts and content. Check out Meetup.com to find user group events. Attend conferences and talk to other people in your sessions, and to the speaker! Most people love to talk about themselves and share their secrets, myself included! Ask questions and absorb details. To find a mentor, don’t just ask anyone, but instead get to know someone by asking questions about their work. Develop a professional relationship to see if you have a rapport, and let the conversation naturally lead to asking someone to mentor you.

Once you are on a path, don’t be afraid to change things up if you aren’t hitting goals or aren’t being challenged. As careers progress, different priorities emerge. Give back to the community by passing on your knowledge to new IT Pros, paying it forward to respect everyone who helped you along your path. Perhaps consulting no longer is ideal and you want to find a steady income as a permanent employee. Keep checking in with yourself, evaluating your impact, and learning new skills. That’s the beauty of the IT Pro, there is always a new rollout on the horizon!

 

Additional resources:

Microsoft Tech Academy

2019 Azure, Office365, and SharePoint Conference list (from Matt Wade)

You Need to Embrace Failure in Order to Truly Succeed (from Mark Rackley)