Showing posts with label guide. Show all posts
Showing posts with label guide. Show all posts

Tuesday, 2 November 2021

Microsoft Exchange - 451 4.7.0 Temporary server error. Please try again later. PRX5 - FIX

I encountered this error on my on-premise/Hybrid exchange server today after noticing that internal mail relay was not working. When attempting to send a test email via telnet, I got the error 451 4.7.0 Temporary server error. Please try again later. PRX5

After rebooting the server, the error still persisted - so a quick bit of searching quickly lead to me adjusting the Exchange servers DNS settings.

From within Exchange Control Panel (ECP) - go to Servers (left hand menu) and double click your Exchange server to open it's properties



Select DNS Lookups from the left menu.

By default, the option for External and Internal DNS lookups is usually All network adapters (All available IPv4). I changed this to Microsoft Hyper-V Network Adapter and the problem was immediately resolved.

Friday, 20 August 2021

Google Classroom - How to get a list of all classes/classrooms

You can use the GAM utility to easily export the details of all Google Classrooms in your domain by following the commands below. In this example we'll be exporting the details to a CSV file

(Be sure to update the path to gam.exe and the output CSV file location)

$allclasses = C:\admin\gam\gam.exe print courses > "C:\Admin\Google Classroom\allclasses.csv"

This works well, but if you look at your CSV file you'll notice that firstly, it isn't formatted into columns properly, and secondly, there are a heap of fields called "coursematerial" that aren't required. We can filter out those fields by using the command below

$allclassesfiltered = import-csv "C:\Admin\GoogleClassroom\allclasses.csv" | select-object * -ExcludeProperty "courseMaterial*"

We can then re-export the CSV file with the command below which will actually export it correctly as a CSV file with data separated into columns correctly

$allclassesfiltered | export-csv "C:\Admin\Google Classroom\allclasses-filtered.csv" -NoTypeInformation


Thursday, 19 August 2021

GAM - How To Sync Google Classroom Students from CSV File

GAM is great command line utility that fills a huge void in the management of Google Classroom - since Google haven't bothered after all these years to create any kind of centralised management interface for the product despite a huge uptake in use from COVID-19 and remote learning.

One of the downfalls of GAM is it can be a little slow - if you wanted to add students individually to a class, the command to add each student takes several seconds to execute - which doesn't sound like much, but in a large school with lots of students and lots of classes - it could take hours to complete.

Thankfully, they have included the ability to synchronise members (students) of a class from a CSV file. What they don't mention in their documentation though is how the CSV file should be formatted - kind of important, right?

The CSV file should be formatted as a basic list - with a single column and no column headings - containing the email addresses of the students you wish to add. If you opened it in Notepad - it would look like the screenshot below

Example CSV file format to sync students to Google Classroom with GAM

One thing to note - if you are going to sync from a CSV file, it will add all the students in the CSV file to the classroom, but it will also remove any students already in the classroom who aren't listed in the CSV file, so it's important your CSV file contains all the students in the class.

The command to run the sync is below;

C:\admin\gam\gam.exe course "googlecourseid"  sync students file "C:\admin\GoogleClassroom\class1.csv"

(Be sure to update the path to your gam.exe file, the google course ID and the CSV file location)

Wednesday, 11 August 2021

Microsoft Teams - How to Archive Teams using Powershell

Microsoft Teams has a great feature that allows users (and administrators) to archive teams instead of deleting them when they are no longer required. This can be convenient as archived teams are no longer visible to users, but can easily be re-activated (or unarchived) if they, or their contents are required in the future - which isn't possible if you delete a team.

To archive a team, use the command below

Connect-MicrosoftTeams

Set-TeamArchivedState -groupid "teamgroupidnumber123" -Archived:$true

Be sure to update the groupid with the unique groupid for the team you wish to archive. If you don't know what the groupid is, run the cmdlet below

Get-Team -displayname "Team Name"

The GroupID will be displayed in the matching results

After the team is archived you can still view it through the Teams Admin Console

Monday, 9 August 2021

Microsoft Teams - Add Members to Private Channel using Powershell

If you have a large number of members you need to add to a private channel in teams, you may wish to use powershell to do so as it can be much faster than manually adding users via the Teams app, or web management interface.

Note that you will need to install the preview/prerelease version of the Microsoft Teams powershell module to get access to the cmdlet that we're using here (refer to my separate blog post on how to do this)

Add-TeamChannelUser -GroupID "abc123456789" -Displayname "privatechannelname" -user "user@domain.com"

Be sure to update the Group ID with the unique Group ID of your target team - and the displayname should match the displayname of the private channel you wish to add the user to.

Note that adding users via this cmdlet can cause them to not show in the actual team for some time (in my experience 15-30 mins) so you may need to allow some time before checking/confirming they appear in the channel user list

Sunday, 8 August 2021

Microsoft Teams - Install Preview/Prerelease Powershell Module

Microsoft Teams has a preview/prerelease version of their powershell module available which has some commands that aren't contained in the general/public release.

If you wish to install the prerelease module, you can use the command below to do so

Install-Module -Name MicrosoftTeams -AllowPrerelease -force

You may need to restart your powershell session and import the module again to get the required cmdlets.

If you get an error saying the 'allowprerelease' argument isn't recognized, then run the below commands ot update the PackageManagement and PowershellGet modules

Install-Module -Name PackageManagement -Repository PSGallery -Force
Install-Module -Name PowerShellGet -Repository PSGallery -Force

Restart your powershell session then run the install-module command again and it should complete successfully.

Wednesday, 4 August 2021

Microsoft Teams - Powershell Administration Commands

 Microsoft Teams has a powershell module available that allows you to perform just about all Teams management tasks using a script. This is very convenient for bulk operations, like creating lots of teams and keeping team memberships up to date - especially since the Teams web admin interface can be quite slow and cumbersome.

Here's a quick guide on some of the most common commands and uses

Install Microsoft Teams Powershell Module

Use the command below to install the Microsoft Teams powershell cmdlets

install-module -name MicrosoftTeams -force

Create a Team

I like to create new teams by using a variable ($newteam) - this makes additional tasks easier since you can reference the unique group ID for the new team directly from the $newteam variable.

$newteam = new-team -displayname "Test Team" -mailnickname "Test-Team" -owner "user@domain.com"

Update the properties for the display name, mailnickname (can't have spaces) and the team owner

Add a User/Member to a Team

If you've created the team like I have above and used a variable like $newteam, you can then use the properties for this variable for other tasks like this

add-teamuser -groupid $newteam.groupid -user "user@domain.com"

Add an additional Owner to a Team

add-teamuser -groupid $newteam.groupid -user "user@domain.com" -role owner

Remove User/Member from a Team

remove-teamuser -groupid $newteam.groupid -user "user@domain.com"


Thursday, 27 May 2021

Searching for String within Multiple Files using Powershell

 I recently had a situation where I had to search for a particular string within a large number of files. More specifically, I was looking for what file contained a set of  text used for a menu on a website - the problem is I didn't know which file contained the text, but I knew what I was looking for. The web server had a large number of xml, html and css files, so I quickly put together a powershell script to search these files quickly and was able to find what I was looking for within a matter of minutes! Certainly faster than manually opening files and performing a CTRL + F find within them.

$files = get-childitem -path "C:\inetpub\wwwroot\*.css" -recurse
foreach ($file in $files)
    {
    $filecontent = get-content $($file.fullname)
    $lookup = $filecontent | select-string "What I'm Looking For"
    if ($lookup)
    {write-host "$($file.fullname)"}
    }

The first line searches the folder C:\inetpub\wwwroot for any file ending in .css.  The -recurse switch means it searches all subfolders within C:\inetpub\wwwroot as well. You can of course change the search directory and file type being searched for

$files = get-childitem -path "C:\inetpub\wwwroot\*.css" -recurse

The next section is a ForEach loop that goes through every file that is found within $files (as outlined above). The content of the file is read into the $filecontent variable

$filecontent = get-content $($file.fullname)

Next we perform a search of all the text within the $filecontent variable for a particular string of text. In this example the text we're looking for is "What I'm Looking For" - change this to whatever string of text you are trying to find tin these files. The result of the search is stored in the $lookup variable. If no match is found then $lookup will be null.

$lookup = $filecontent | select-string "What I'm Looking For"

Finally, if a result is found and the $lookup variable is not null, the full name of the file is written to the screen

if ($lookup)
    {write-host "$($file.fullname)"}

This little script saved me a heap of time - as built in windows search functions are pretty unreliable and don't search for content within files. Hope it is able to help you as well.

Friday, 7 May 2021

Connect to Office365/O365 using Powershell

A quick an easy post with details on how to connect your Office 365 (O365) environment to allow management with powershell cmdlets

Make sure you change the value next to -Credential from username@domain.com to the username you need to use to connect

$ex = New-PSSession -ConfigurationName Microsoft.Exchange -Credential username@domain.com -ConnectionUri https://outlook.office365.com/powershell -Authentication basic -AllowRedirection

import-pssession $ex

After executing this command, a popup window will appear for you to enter your password into



You will then receive a couple of warning messages to indicate that your session has been redirected to a slightly different URL, and another about some of the imported commands. These can be safely ignored

WARNING: Your connection has been redirected to the following URI: "https://outlook.office365.com/PowerShell-LiveID?PSVersion=5.1.17763.1852 "
WARNING: The names of some imported commands from the module 'tmp_4kculvlx.2wc' include unapproved verbs that might make them less discoverable. To find the commands with unapproved verbs, run the Import-Module command again with the Verbose parameter. For a
 list of approved verbs, type Get-Verb.

You can then proceed to manage your Office 365 environment with the standard powershell commands - get-mailbox etc.


Wednesday, 12 October 2016

Windows - Unable to remove printer driver - The specified printer driver is currently in use

Sometimes you may need to uninstall a printer driver from a computer (because of corruption, to re-install etc), and may get the below error message;

"Unable to remove printername. The specified printer driver is currently in use"



This may even occur AFTER you have removed the printer itself from your list in Devices & Printers.

Here are some steps I found that allowed me to remove the printer and printer driver without having to restart the computer;


  1. Open Devices and Printers
  2. Right click the device you need to remove and select Remove Device
  3. Open Services.msc and locate the Print Spooler service
  4. Right click the Print Spooler service and select Stop
  5. Open regedit
  6. Browse to the key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Environments\
  7. Depending on whether you are running a 32 or 64 bit windows, expand the key for Windows NT x86 (if you're running 32 bit windows), or Windows x64 (if you are running 64 bit windows)
  8. Expand the Print Processors key
  9. Rename any entries under Print Processors to have .old on the end. In the example below, there is one entry, winprint which I renamed to winprint.old

  10. Go back to services.msc and start the Print Spooler service
  11. Open the Print Server Properties and try to remove the driver pack - it should now remove successfully
  12. Once the driver pack is removed, stop the Print Spooler service again
  13. Go back to regedit and rename the key(s) you renamed to have .old on the end back to their original name(s) - as per my example, winprint.old will be renamed back to winprint
  14. Start the Print Spooler service from services.msc
  15. Re-install printer & drivers as required




Monday, 10 October 2016

iPod/iPhone/iPad not appearing in iTunes

I occasionally experience an issue with my iPod, where after connecting it to my laptop via USB, and having the iPod appear in Windows Explorer, it won't appear as a device in iTunes

iPod showing in Windows Explorer but not iTunes

Follow the steps below to fix the issue;


  1. Close iTunes if you already have it running
  2. Click on the Start button (bottom left corner of screen) and type services.msc and press Enter
  3. A new window will now open showing a list of all windows services. Sort the list by name and locate the Apple Mobile Device Service
  4. Right click on this service and select Restart

  5. Once the service has restarted, locate the iPod Service. Right click on this service and select Restart

  6. Open iTunes. Your iPod/iPhone should now appear within iTunes correctly


Friday, 7 October 2016

Fix Windows Update Error Code 80070003

I got this error code today on a Windows 7 PC after trying to install some windows updates



Code 8007003
Code 643

To fix it, follow the steps below;
  1. Click on the Start button (bottom left corner) and types services.msc and press enter (to open the Services control panel)
  2. Locate the Windows Update service. Right click it and select Stop


  3. Open Windows Explorer. Navigate to the folder C:\Windows\SoftwareDistribution\Download folder. Delete everything within this folder - (this is where the windows updates are downloaded to before being installed)
  4. Go back to your list of services from Step 2. Right click the Windows Update service and select Start
  5. Go back to your windows updates and click Check for updates again and proceed to install them as you normally would




Thursday, 29 September 2016

iPhone/iPad - Cannot send mail. A copy has been placed in your Outbox. The recipient was rejected by the server

Occasionally I've seen users experience an issue where they can no longer send emails to anyone from their iPad or iPhone, they get the below error message;

"Cannot send mail. A copy has been placed in your Outbox. The recipient %name% was rejected by the server"

The issue is usually caused by the authentication (ie. username and password) failing for the email account, because it is either missing or incorrect.

I've often seen this happen after iOS updates, as passwords for email accounts aren't always preserved during the update process. As a result, the password appears to be present (when you check the settings), but actually isn't, and therefore emails won't send any longer.

To fix the issue, do the following on the problematic device(s);


  • Go to Settings
  • Go to Mail

  • Select Accounts

  • Select the account that you are having problems sending from

  • Select the account again (first option at top of screen)

  • Update the Domain, Username and Password fields. Even if the password appears to be in there (represented by black circles), delete whatever is in there and re-type the password

  • Click Done from the top right corner. Settings should now be checked and you should get a list of ticks down the ride side of the page
If the settings saved successfully you can try sending emails again, it should now work correctly.

Monday, 19 September 2016

iTunes could not connect to the iPhone because an invalid response was received from the device

I encountered this issue on my home PC after getting my new iPhone 7. I had previously sync'd the phone with my laptop, but upon connecting it to my PC, I got the error message;

"iTunes could not connect to the iPhone because an invalid response was received from the device"

I was pretty confident the phone wasn't the issue as it had successfully sync'd with another computer - I tried the following steps first which did not fix the issue;


  • Different USB/lightning cable
  • Different USB port
  • Rebooted computer
  • Rebooted iPhone
  • Ensured iPhone wasn't locked when connecting
  • Removed iPhone device from device manager
What ended up fixing the issue in the end was uninstalling and re-installing iTunes on the computer.

Wednesday, 7 September 2016

Restoring Files & Folders from Backup - Macrium Reflect

As outlined in my previous blog post, we have setup a full backup of your PC using a free and easy to use product called Macrium Reflect.

Once you have a full backup image file available, you can open, explore and restore files from it which is what we'll be covering in this blog post.


  1. Open windows explorer and browse to the location of your Macrium Backup image file (the file will have .mrimg on the end of it)
  2. Right click on the image file and select "Explore Image"

  3. Macrium will now load a "Backup Selection" screen where you can select which of the hard drives you backed up you wish to "mount" in windows explorer. In most cases (and this example), there will be one drive available (C:), so select it by placing a tick in the box next to it then click OK.

    You can also select the option to "Enable access to restricted folders" if you wish to access files that would normally be restricted (such as files in another users profile/account)
    Also note the "Drive Letter" that is specified - in this case H:\

  4. Windows Explorer will now mount the image and open Windows Explorer to show the files contained within it. As per the screenshot below, you can see H:\ is available and is called "Macrium Reflect Image". From here, you can view/browse all the files within the image. If you wish to restore/recover files from within this image, you can simply copy and paste them from this image drive, back to your C:\ or other folder as required

  5. Once you are done, you need to "unmount" the macrium image file. To do this, right click the macrium image drive letter (H:\ in this example), then go to go Macrium Reflect > Unmount Macrium Image

Wednesday, 26 March 2014

Get Folder Size (including subfolders) with Powershell

The method for obtaining the size of all items within a folder using Windows Powershell is unfortunately not as straight forward as it probably should be. The method outlined below is very useful for querying multiple folders to determine the size of all items inside, including all subfolders and files.

$dir = "C:\temp"
$totaldirsize = (get-childitem $dir -recurse -force | measure-object -property length -sum)

The first variable sets the directory that we wish to query - in this example it is C:\temp.

Next, we use a get-childitem to query the directory. The -recurse and -force switches mean that all sub directories and files are also included. We then pipe the results to measure-object and calculate the length of each child item (which is actually the size in bytes) and use the -sum switch to add them all up.

If you run the above command, and then look at the $totaldirsize variable, you will see something like below;

PS C:\> $totaldirsize

Count    : 38
Average  : 
Sum      : 51652089
Maximum  : 
Minimum  : 

Property : length

So from this we can see there are 38 items in total in the C:\temp directory, and the sum of all files is 51652089 bytes. To make this more useful, we can easily convert this value to KB, MB or GB

$mbsize = $totaldirsize.sum / 1MB

If we now look at $mbsize, we'll usually have an integer with a large number of decimal places. In this example, the result I got was 49.2592706680298. So as a final step, I'd like to round this number to 2 decimal places

$mbsize2 = "{0:N2}" -f $mbsize

Now if we look at the value of $mbsize2, the result is 49.26.

You can change the 2 in {0:N2} to any other digit to round the number to that many places after the decimal point.

Tuesday, 5 February 2013

Creating Custom Tables in Powershell

When working with scripts, it is often necessary to collect, store and present information in a table format. An example of this could be to export a number of properties from a users mailbox in Exchange into a table format.

For my example, I will run the following command to export all the properties of a mailbox (mine) to a variable called $UserList

$UserList = get-mailbox -ResultSize Unlimited | Where-Object {$_.DisplayName -eq "Morrissey, Peter"}

The next thing to do is to declare/create the table. It can be called anything you like, but I tend to use $report. The following line of code creates the table;

$report = @()

Next, you need to populate each row of your table with whatever fields you require. This would usually be done with a ForEach statement where you cycle through a list of objects, with numerous properties for each object.

In my example, the object list is stored in $UserList. I can run the command $UserList | fl to display the list of all the properties available for each object in my variable.

This ForEach command will cycle through each entry in $UserList (in my example it is only a single entry for my mailbox) and add whatever properties of that object I declare into the table (I have used DisplayName and Database) but you can use as many as you like - they just need to be separated by a semi colon (;)

ForEach ($User in $UserList)
             {
             $report += New-Object psobject -Property @{DisplayName=$($User.DisplayName);Database=$($User.Database)}
             }

This is a simple example and will create a table with two values for each row; DisplayName and Database.

Once you have populated all the rows you require in your table, you can then export it to a CSV file using the following command;

$report | select DisplayName, Database | Export-CSV -path "C:\ReportOutput.csv"

Once again, you will need to replace $report with whatever variable you used to declare your table. You also need to use the Select component to select all the table fields you wish to export into the CSV file - in my case it was the DisplayName and Database fields.

Finally, once the CSV file is exported, you can then attach it to an email and send it to yourself (or someone else) as outlined in my previous blog post.

Tuesday, 29 January 2013

File Locked After Sending SMTP Email with Powershell

In my previous blog post about sending emails with Powershell, I mentioned a problem where files that you attach to an email become locked until the instance of Powershell you are running has exited completely. So if you run a script through Powershell ISE that attaches a file to an email, that file will remain locked until you exit Powershell ISE.

If the file is locked by Powershell, you will get an error/warning message similar to the following if you try to modify it in any way;

The process cannot access the file 'c:\filename.txt' because it is being used by another process

By using the following command, you can ensure that Powershell 'disposes' of the email message once it has been sent and does not continue to 'lock' any files you attach and send via email;

$mailmessage.dispose()

Note: this is assuming that $MailMessage = New-Object system.net.mail.mailmessage 

Friday, 25 January 2013

Sending Email Messages with Powershell

A lot of the scripts I use generate reports or .csv files that I need to reference or send to other users who have requested them. One of the easiest ways to accomplish this is to configure your script to automatically email yourself (or anyone else) with the results and/or any files that were created in your script. This saves you time by not having to manually copy the files to another location or attach them to a new email message. You can simply receive the email message and forward it on, or include all recipients in the original email sent by the script.

The following lines of code can be used to create and send an email message with Windows Powershell:


$SmtpClient = new-object system.net.mail.smtpClient 
$MailMessage = New-Object system.net.mail.mailmessage 
$SmtpClient.Host = "your.smtp.server" 
$mailmessage.from = ("fromaddress@yourdomain.com") 

$mailmessage.Subject = “Subject”
$mailmessage.Body = "body text"
$mailmessage.IsBodyHtml = $true
$mailmessage.ReplyTo = "replytoaddress@yourdomain.com"
$mailmessage.Attachments.Add("C:\Path\yourfile.txt")
$smtpclient.Send($mailmessage)
$mailmessage.dispose()

Notes:

You will need to replace the values in some of the variables above to allow it to work in your environment (ie. SmtpClient.Host, FromAddress, Subject, Body text, Reply to address, attachment path).

You will also need to ensure that whatever machine you are running this script on is "authorised" to send with the SMTP server you have configured.

The final line of code $mailmessage.dispose() is very important when sending emails with attachments. If this line is not included, Powershell 'locks' the file(s) you attached after the message has been sent and will not 'release' them until the Powershell instance you are running is closed.

Wednesday, 23 January 2013

Creating a Graphical User Interface (GUI) with Powershell

One of the first things I wanted to do when I started learning Powershell was to create a simple graphical user interface (GUI) that I could use to automate some of my day to day tasks. One main task in particular that took up a lot of my time was creating new user accounts. The process involved creating an Active Directory account, attaching a new mailbox to the Active directory account, adding the new account to security and distribution groups, and also sending a notification email to the new account requester with all the information in it. Doing this process manually was incredibly time consuming, and I knew there had to be a better way.

By using Powershell, I created a script that prompts with several input boxes and list boxes where I can enter all the required details to create a user account. All these inputs are saved as variables, and can then be used to run a single command to perform all the necessary steps.

Here is a screenshot of one of the input boxes that is presented during the script:


By repeating this prompt for first name, last name, office, department, title, phone number, password etc, I was able to quickly and easily collect all the information I needed to create an Active Directory account using the dsadd command - which also runs as part of the script once all the information has been collected.

Once I had an Active Directory account created, I was then able to create a mailbox and attach it to the Active Directory account using the Enable-Mailbox cmdlet.

And finally, once the Active Directory account and mailbox were created,  I could add the user to any required security/distribution groups, and send all the new account information via email to the requester. (I will cover each these topics in more detail in future blog posts.)

One of the most valuable things you can teach yourself with Powershell is how to create input boxes and list boxes for the collecting of information you require to run a command. Some examples of such commands are creating user accounts (as I just discussed), enabling or disabling ActiveSync on a mailbox, or enabling/disabling email forwarding. The possibilities are endless, though most of mine focus around the Active Directory/Microsoft Exchange technologies.

This Technet Article is what I used to get started on input boxes and highly recommend it as a starting point as the article breaks down each line of code and explains what it does.

Once you learn how to create, modify and use input boxes, you can apply the same lines of code over and over again within all your scripts - invest the time to learn it and it will save you time in the end, and open up enormous possibilities/options for your Powershell scripting.