Google and Yahoo!, in an effort to reduce spam and phishing, both recently announced tighter security requirements for emails sent to the gmail.com and yahoo.com email domains. The major consequence of this is that anyone who manages an email service no longer has any excuses to not implement long-accepted best practices regarding email security. Those best practices are now effectively mandatory if you wish for email emitted from your domain to reach the bulk of recipients. And it isn’t just email admins who have to worry about this. Anyone who is a customer of bulk-email services such as Constant Contact or Emma (or any other 3rd party service that might need to send email that seems to come from your domain) also has to deal with this.
ChatGPT Writes PowerShell Scripts…Badly
One of the most intriguing features of ChatGPT is its ability to take a plain-English description of desired functionality and turn that into a simple script or program in a variety of programming and scripting languages, including PowerShell.
Unfortunately, it doesn’t do this well.
Cisco AnyConnect breaks network connectivity in Ubuntu running under WSL
Get-NetAdapter | Where-Object {$_.InterfaceDescription -Match "Cisco AnyConnect"} | Set-NetIPInterface -InterfaceMetric 4000 Get-NetIPInterface -InterfaceAlias "vEthernet (WSL)" | Set-NetIPInterface -InterfaceMetric 1
Tricking PowerShell Into Treating a String as a Stream
The PowerShell cmdlet Get-FileHash accepts only files or streams as inputs. If I want to generate a hash for a string, I could save it as a file and then feed that file to the command, or I could simply send the string to the command as a string:
PS C:\Working> $stringStream = [System.IO.MemoryStream]::new() PS C:\Working> $writer = [System.IO.StreamWriter]::new($stringStream) PS C:\Working> $writer.write("Please hash me.") PS C:\Working> $writer.Flush() PS C:\Working> $stringStream.Position = 0 PS C:\Working> Get-FileHash -InputStream $stringStream | Select-Object Hash Hash ---- 50981297AEA627CA3AA5026EB31475FAFD0D28D430165506A2A69B7A30C36AC6
PowerShell Hash Tables
A hash table is an array of key/value pairs, along with accompanying functions for
readily accessing or modifying values by way of their corresponding keys. Continue reading
How to setup your Office 365 email using Evolution-EWS (Linux)
A variant of the Evolution email client for Linux is available which utilizes the Exchange-native Exchange Web Services (EWS) API to access and manage Exchange mailbox content, including Calendar data. For Linux users, this represents the best available option for connecting Office 365 Exchange Online aside from the Outlook Web App.
(Note that this information is provided for informational purposes only. This is not an officially supported client in our environment.) Continue reading
Using PasswordVault with PowerShell
A handy way to securely store credentials for use by a PowerShell script (particularly one running from within a Scheduled Task) is to use the Windows PasswordVault class. Please note that this should not be confused with the Credential Manager module.
Credentials are store and incrypted in the PasswordVault on a per-user basis. If credentials are being stored for use by a Scheduled Task, be sure to login to the system and stash the credentials using the account that the Task will be running under. Continue reading
Accessing Shared Calendars or Inboxes via OWA App
NOTE: The OWA App is no longer supported.
A longstanding hindrance in getting customers to agree to switch to using actual shared or resource mailboxes as opposed to User mailboxes (tied to guest accounts, which our ISO frowns upon) posing as role-based mailboxes or rooms has been their need to access such mailboxes via mobile devices. This stems from the limitation of ActiveSync not permitting access to multiple mailboxes in an Exchange service via a single set of credentials.
I’ve now found a workaround for this limitation using the OWA App for iPhone, iPad, and Android. There is a trick to accomplishing this, and it is not well documented, but after much fiddling, I’ve managed to figure it out.
The secret is to start in OWA. Not the app, but browser-based OWA. The following steps have to be done in OWA. It will not work to do this in the Outlook desktop app. Suppose I have permissions to access the Inbox and Calendar folders of a room resource mailbox. Here are the steps to expose those folders to me in the OWA App.
- Start off by logging into OWA.
- In the left-hand navigation bar under “Folders”, click “More” to expose the full folder list.
- Below the Favorites list, there should be a line with your mailbox name. Right-click that and select “Add shared folder…”
- In the “Add shared folder” dialog, search the directory for the desired mailbox and click “Add”.
- Now, from the “waffle” app launcher icon, select “Calendar”
- In the left-hand navigation bar, right-click “My Calendars” and select “Open calendar”.
- Once again, find the target mailbox and click “Open”.
Now that everything is staged in OWA to expose the shared mailbox, we can move on to configuring the mobile OWA App. Please note that, if you’ve already configured your account in the OWA App, the shared folders won’t auto-populate in the folder list in the app. We actually have to reset the app and configure it from scratch to force a refresh of the listing. To do so, perform the following steps. (These are the steps for doing so on iOS. Android users will need to figure out the corresponding steps on their own since I don’t have an Android device with which to test.)
- On the iOS device, close the OWA app if it is already open. (Double-press the main button, scroll left or right to find the running app, and swipe up to kill it.)
- Open the Settings app and scroll down through the listing of apps to find the entry for OWA, then select it.
- Turn the “Reset Application” setting ON.
- Now, go back to the main screen and turn on the OWA app.
- Tap on “Continue” on the “Before you start” screen.
- Enter your email address and tap “Sign in”.
- You’ll then be prompted to enter your password. Do so and tap “Sign in” again.
- Now, once you are fully logged into your mailbox, tap the three-bar “hamburger” icon in the upper left-hand corner.
- This will expose the list of available mailboxes and folders.
- Expand the mailbox you added earlier in OWA to show its list of folders, then tap the folder you wish to view. Lo and behold, the selected folder will then be displayed.
- To see the calendar of the mailbox you’ve added, click the calendar icon at the bottom of the screen.
- Click the previously-mentioned control icon in the upper left-hand corner to expose the calendar list.
- Tap the calendar you wish to view. (You may wish to de-select your own default calendar at the top of the list. Otherwise, the resulting view will present a superposition of both calendars.)
- Tap the previously used control to bring the calendar view back in place.
And there you have it. Viewing shared or resource mailbox items (or even shared items from another user mailbox) in the OWA App for mobile devices.
Exploring Delegates with the EWS Managed API – Part I: The EWS Delegate Functions
As an Exchange administrator, a long-standing source of frustration for me has been the fact that Microsoft does not provide tools for administratively inspecting and repairing delegate settings. Apart from granting Full Access permissions on the mailbox and logging into it with Outlook, all an Exchange admin can really do is inspect the GrandSendOnBehalfTo attribute (a.k.a. publicDelegates), tinker with relevant folder sharing permissions, and use MfcMAPI to nuke the hidden delegate forwarding rule when it is misbehaving, which is rather drastic as it stops ALL delegate forwarding for that mailbox.
Well, there is another option: turning to (or building) the tools to do the job. A fine example of just such a tool is the MessageOps EWS PowerShell Module, which builds upon Exchange Web Services to add a host of Exchange commands to PowerShell, including tools for dealing with delegates. While it is a fine tool which I’ve found quite useful, I got it into my head to write my own set of delegate management tools, if for no other reason than to get a better handle on how delegates actually work under the hood. In short, I’m a glutton for punishment, so I set about re-inventing the wheel…. Continue reading
Talking to SQL via PowerShell
Interacting with a SQL database from PowerShell is pretty simple. In the example I give below, it is assumed that 1) the appropriate ODBC data source has been configured on the machine from which the commands are being executed, and 2) the account under which the script commands are being run has the appropriate privileges on the SQL database.
First of all, let’s define a few variables:
$dataSource = “sqlserver.domain.com”
$database = “MyDB”
$auth = “Integrated Security=SSPI;”
$connectionString = “Provider=sqloledb; ” +
“Data Source=$dataSource; ” +
“Initial Catalog=$database; ” +
“$auth; “
Now, here’s the really critical variable: the SQL query itself.
$sql = “SELECT * FROM tbl_MyTable”
Now for the heavy lifting, where we instantiate an OleDb database connection object, populate it with the appropriate parameters, and tell it to do its thing:
$connection = New-Object System.Data.OleDb.OleDbConnection $connectionString
$command = New-Object System.Data.OleDb.OleDbCommand $sql,$connection
$connection.Open()
$adapter = New-Object System.Data.OleDb.OleDbDataAdapter $command
$dataset = New-Object System.Data.DataSet
[void] $adapter.Fill($dataSet)
$connection.Close()
$rows=($dataset.Tables | Select-Object -Expand Rows)
That really is all that there is to it. The returned rows are all in the $rows variable, ready for whatever munging you need to do.
Happy PowerShelling….