Azure – What tags are we using again…?

2017-07-27T00:00:55+00:00 July 7th, 2017|Azure, blog, PowerShell|

Have you wondered what tags are assigned to all your Azure VMs?  Do you not have ARM Policies in place to enforce your preferred tags yet?

I was in just such a situation the other day.  Just like in my previous post on quick Azure-related scripts, I was working with a customer that just wanted a quick utility to report on what VMs are properly tagged (or not) in their implementation, without having to fish around the Portal.  No ARM Policies there yet…  *yet*.

So I whipped this together.  And much like that previous script, you just paste this into a PS1 file, set the subscription name in the variable, and then run it.

# GetVmTags - Jeremy Pavlov @ Coretek Services 
# Setting the subscription here
$MySubscriptionName = "My Subscription"
# Set some empty arrays
$vmobjs = @()
$vmTagsKeys = @()
$vmTagsValues = @()
# Get the VMs...
$vms = Get-AzureRmVm 
#
$NeedToLogin = Read-Host "Do you need to log in to Azure? (Y/N)"
if ($NeedToLogin -eq "Y")
{
  Login-AzureRmAccount
  Select-AzureRmSubscription -SubscriptionName $MySubscriptionName
}
elseif ($NeedToLogin -eq "N")
{
  Write-Host "You must already be logged in then.  Fine. Continuing..."
}
else
{
  Write-Host ""
  Write-Host "You made an invalid choice.  Exiting..."
  exit
}
#
foreach ($vm in $vms)
{
    Write-Host ""
    $vmname = $vm.name
    $MyResourceGroup = $vm.ResourceGroupName
    Write-Host "Checking tags for VM $vmname... "
    Start-Sleep 1
    $vmTags = (Get-AzureRmVM -name $vmname -ResourceGroupName $MyResourceGroup).Tags
    $vmTagsCount = $vmTags.Count
    if ($vmTagsCount -gt 0)
    {
      $vmTagsKeys = $vmTags.Keys -split '
[\r\n]' $vmTagsValues = $vmTags.Values -split '[\r\n]' for ($i=0;$i -lt $vmTagsCount; $i++) { $CurrentTagKey = $vmTagsKeys[$i] $CurrentTagValue = $vmTagsValues[$i] Write-Host -ForegroundColor Green "Key : Value -- $CurrentTagKey : $CurrentTagValue" } } else { Write-Host -ForegroundColor Yellow "No tags for $vmname" } }

The results should look something like this, except hopefully a lot more serious and business-y:

Have fun with it, change it up, and let me know what you do with it…   I hope it helps.  Enjoy!

Is Microsoft Really Going “Open”?

2017-07-27T00:00:58+00:00 April 14th, 2016|Azure|

Coretek Cloud Logo final

Many customers aren’t aware of the major shift Microsoft has been making over the last few years.  Microsoft SQL on Linux is a culmination of those changes.  With the announcement of Red Hat support and .Net on Linux, Microsoft has made a major move in the open source marketplace.

Did you know that almost all of the features in System Center 2013, OMS, Azure Backup, and Azure Site Recovery, treat Linux as an equal class citizen?  Windows — or Linux — is no longer a sticking point on the solutions we design and deploy.  With Windows or Linux we can deliver operational solutions on any platform.

 

Let us know if you have a unique requirement that has been challenging to your business, we are very confident we can help.

 

Jason M. Cornellier – Cloud Practice Director

 

http://blogs.microsoft.com/blog/2016/03/07/announcing-sql-server-on-linux/

http://blogs.microsoft.com/blog/2016/02/24/microsoft-to-acquire-xamarin-and-empower-more-developers-to-build-apps-on-any-device/

http://blogs.microsoft.com/blog/2015/11/04/microsoft-and-red-hat-partner-to-deliver-more-flexibility-and-choice/

http://www.dotnetfoundation.org/

http://www.computerworld.com/article/3052881/microsoft-windows/microsoft-brings-bash-to-windows-with-new-beta-build.html

 

PowerShell – Query AD for Group Email Addresses…

2014-09-10T22:11:03+00:00 September 10th, 2014|Uncategorized|

Somebody asked me today if there is an easy way to query AD or Exchange for the email addresses of groups.  There most certainly is!  Let’s walk through my train-of-thought here.  First, I started by querying all groups, piped to Format-List, like this…

Get-ADObject -LDAPFilter "(objectclass=group)" -Properties mail|fl

…but in doing so, you get this list of group objects that may or may not have email addresses:

PowerShell Group Email Query

Hmm, we can do better…  Do you want to query ALL groups, or just groups with email addresses?  Well, in our case, we’re really just after groups with email addresses, so I modify my ldap filter accordingly:

Get-ADObject -LDAPFilter "(&(objectclass=group)(mail=*))" -Properties mail|fl

And the results look the same as above, but only the groups we want are listed.  Okay, that’s better.  But of course, if you ONLY want the email addresses, let’s limit the properties in our list:

Get-ADObject -LDAPFilter "(&(objectclass=group)(mail=*))" -Properties mail|fl -Property mail

…and it looks like this:

PowerShell Group Email Query 2

And finally, if you just want the list of email addresses, no attributes; we use the PowerShell equivalent of AWK to split the line…

Get-ADObject -LDAPFilter "(&(objectclass=group)(mail=*))" -Properties mail|fl -Property mail|findstr /v "^$"| %{ $_.Split(' ')[2]; }

And here’s our pretty list:

PowerShell Group Email Query 3

 I hope that helps!

Managing Multiple Azure Subscriptions from PowerShell…

2017-07-27T00:01:01+00:00 July 24th, 2014|Uncategorized|

Hi folks, Jason here again – this time with some Azure PowerShell goodness to share.

A while back I set up an Azure trial subscription.  Following Jeremy’s post last year, “How to manage Azure from PowerShell on your PC“, I was able to get PowerShell to connect to my free trial subscription, creatively named “Free Trial”.  Coretek was kind enough to provide me with an MSDN Premium license.  Since the MSDN Azure subscriptions get $99 a month in Azure credit, it was high time to switch over to that Azure account and leverage that credit!  This subscription was also creatively named… “Visual Studio Premium with MSDN”.

Once again I followed Jeremy’s steps to import the Azure Publish Settings file – this time for the new subscription.  I ran Get-AzureVM… but I wasn’t seeing any VMs for my MSDN subscription.  Take a look:

http://www.coretekservices.com/sites/default/files/20140724/azuresub1.png

…In the above screen capture, XENAPP1 is a VM in my old, un-loved Free Trial subscription.  Running Get-AzureSubscription showed me that I did indeed have access to two subscriptions, as expected:

http://www.coretekservices.com/sites/default/files/20140724/azuresubnames.png

So that begged the obvious question… how do I connect to my VMs in my other subscription?  Well that’s easy enough to do.  Just run the following cmdlet:

Select-AzureSubscription –SubscriptionName “Visual Studio Premium with MSDN”

…of course, change the subscription name to match your own.  NOTE: the subscription name is case sensitive!

One more tip for you, Dear Reader.  If you close your Azure PowerShell window and come back, it will revert back to whatever subscription is the default subscription.  That will always be the first subscription you set up.  The fix is simply adding the –Default switch to the end of the above cmdlet.  Now that’ll be where your Azure cmdlets do their magic as you go forward.

Now when I run Get-AzureVM I get the VMs I am looking for:

http://www.coretekservices.com/sites/default/files/20140724/correctazurevms.png

😎

Azure PowerShell Errors Pt. 2…

2017-07-27T00:01:01+00:00 July 16th, 2014|Uncategorized|

In Part 1 of this 2-part series, I showed you how to re-install in order to eliminate the errors.  But at the end of that post, you surely noticed that while I fixed one problem, I seemigly created another.  Now it appears that I have red error text because it can’t load my profile script, and tons of scripts prompting me to execute.  It looked like this:

Unexpected Azure Errors...

This is strange… because I’m fairly certain my ExecutionPolicy is set to something lower, like RemoteSigned…  Hmm.  Let’s take a look at what my *combined* policy is set at, by issuing the Get-ExecutionPolicy -List command like this:

Get-ExecutionPolicy -List

That’s strange too.  But I see now that there’s a limiting policy on the *process*, so at least I know why this is happening (by the way, ignore that Unrestricted on LocalMachine 😉 ).  Clearly, I’m shooting myself in the foot with the cumulative permissions.  So, let’s try and figure out how that restriction is getting set on my system by chasing down the PowerShell link.  Right-click on the Windows Azure PowerShell icon and choose Open File Location:

Open File Location

Then, right-click on the Windows Azure PowerShell link and choose Properties.  And guess what we find:

Windows Azure PowerShell Properties

Yes, it appears that the shortcut/tile/link has hard-coded the ExecutionPolicy of AllSigned, which means it will permit only execution of — and request your validation of — certificate-signed scripts. 

Aside: This is where I tell you that normally, using AllSigned is probably a good thing; and although I’m not making an official recommendation of lowering that setting in production, I will tell you honestly that I typically use RemoteSigned on my laptop and feel it to be sufficient for my needs. 

So with that clarification out of the way, let’s change this setting and make our life a lot easier.  To do so, change:

C:WINDOWSSysWOW64WindowsPowerShellv1.0powershell.exe -NoExit -ExecutionPolicy AllSigned -File "C:Program Files (x86)Microsoft SDKsWindows AzurePowerShellAzureShortcutStartup.ps1"

…to (you will be prompted for Administrator-level permission):

C:WINDOWSSysWOW64WindowsPowerShellv1.0powershell.exe -NoExit -ExecutionPolicy RemoteSigned -File "C:Program Files (x86)Microsoft SDKsWindows AzurePowerShellAzureShortcutStartup.ps1"

…and now things should be back to normal. 

Normal Azure Startup - Hooray!

Look!  Even my startup script runs now.  Ah…  Feel that?  It’s Azure Zen goodness…

 

 

Azure PowerShell Errors Pt. 1…

2017-07-27T00:01:02+00:00 July 10th, 2014|Uncategorized|

Following up my original post from last year, “How to manage Azure from PowerShell on your PC“…

If you haven’t updated your Azure PowerShell installation in the last few months, you very well may be seeing errors that say Requested value (something) not found, like this:

Requested Value (something) Was Not Found

The first thing you should do is to go to Control Panel -> Programs, and take a look at the version of the Windows Azure PowerShell listed there.  But, I suspect that if you’re reading this, you already know it’s older and out of date…  like mine was:

Azure PowerShell Old Version

How do you fix it?  Easy.  Just re-install on top of the existing.  In fact, if you go back to my original installation post and follow the install process, it will put in the newest, correct version.  After clicking the installation link, the Web Platform Installer launches, like this:

Web Platform Installer

If you click on “options”, you’ll see what it will be installing…

Web Platform Installer Details

Upon launch, you have to allow the startup scripts to run (Why is this?  More on this in Part 2!)…

Azure PowerShell Accept message...

…and allow, and allow, and allow (again, more on this in Part 2)…

Azure PowerShell Accept and Accept...

And finally, you should be good to go.  Your Programs listing should now look more like this:

Azure PowerShell New Version

…and once again, your shell should look like it once was:

Azure PowerShell Working Again

Happy Azuring!

😎

 

Using Powershell to check password properties…

2017-07-27T00:01:02+00:00 December 5th, 2013|Uncategorized|

Thanks to Mike Driest, who did most of the testing and documentation on this issue…

One of the many benefits of Coretek’s Virtual Clinical Workstation (VCW) solution is the ability to allow users to run their clinical applications through a “thin” client.  A thin client is a small, lightweight computer that contains very little hardware; just the minimum to allow them to connect to more high powered servers on which their applications run.  

Some of these thin clients run a smaller, “lighter” version of  Windows called Windows “Embedded”, while others don’t run Windows at all!  These devices — while being very inexpensive and convenient due to their small footprint (space wise and energy wise) — pose certain technical challenges in a Windows environment.  One such challenge is the ability to change a user’s Active Directory domain password.

We had to do some troubleshooting recently in our lab to determine whether we had the correct settings to allow an Imprivata “service” account to facilitate a domain user password change from a “zero” client – a device that does not run any form of Windows.  As part of our testing, we had to ensure that the test account’s password was expired; to do this in a timely manner, we set the “pwdLastSet” attribute of the test account to ’0′ (zero):

To confirm that the password was indeed expired we used the following PowerShell command (requires the AD DS PowerShell Snap-In)

“Get-ADUser SamAccountName -Properties *”

You’ll see “PasswordExpired: True” and “PasswordLastSet” is blank. 

Before: 

 

After:

 

 I hope you find this tip helpful!

Powershell with embedded VBS…

2017-07-27T00:01:03+00:00 November 21st, 2013|Uncategorized|

I recently have been working on a project where the client uses an application that requires a generic username and password to be passed to the database.  To further complicate the matter the users could not know or input the username/password…

To accommodate the project I started working with the logic and how to accomplish this goal.  I started Imprivata (A Single Sign on Application) and AppSense to launch the app at the end of the userinit process.  Unfortunately, this failed to function due to the outdated server version at the client site.  So I ended up with PowerShell to launch the application…

I wrote 26 lines of code (see below) to check if the script had been run before; if it hadn’t, then it would create a flag.  Once it completed, it would check the flag, run the script, expect Imprivata to proxy the credentials, and the day was saved, right?!? 

 

# Create Windows Shell Object to allow for window to be minimized
$shell = New-Object -ComObject "Shell.Application"
# Create Registry Key Flag if it doesn’t already exist
if (!(test-path -path HKCU:SoftwareCUSTOMER -pathType container))
{
  New-Item -Path HKCU:Software -Name CUSTOMER
  New-ItemProperty "HKCU:SoftwareCUSTOMER" -Name "SynapseLaunched" -Value 0 -PropertyType "DWord"
}
#Check the value of Synapse Launched
if ((Get-ItemProperty 'hkCU:softwareCUSTOMER' -name SynapseLaunched | select -exp SynapseLaunched) -ne 1) 
{ 
  #launch Synapse then minimize all windows
  & 'C:Windowsexplorer.exe' "::{1FBD11EF-1260-11D1-87A7-444553540001}"
  start-sleep -s 2
  $shell.minimizeall() 
  #countdown from 2 seconds to allow app to connect to server
  Start-Sleep -s 2
  #kill Explorer.exe and relaunch
  $proc = Get-Process
  foreach ($objItm in $proc) 
  {
    If ($objItm.ProcessName -eq "explorer") 
    {
       kill $objItm.ID
    }
  }
  #Set SynapseLaunched Dword Value to 1
  Set-ItemProperty 'hkcu:softwareCUSTOMER' -name SynapseLaunched -Value 1  
}  

…Sadly, not so.  Imprivata at the client site was outdated and would not be available to be used for Windows 7 at the site for 2 months, causing an unacceptable delay in the project. 

Well, after the Imprivata approach failed for me, I needed to accomplish what I couldn’t do in Imprivata.  I started by thinking that perhaps I could launch an explorer process (this app is an explorer shell extension) as run as user with my username…  But no dice; the launching of explorer like that didn’t work because it would cause the files I needed to be created in a non-existent user profile, and would error out on the server.

So, I fell back to Windows VBS scripting’s SendKeys.  Since my script was already in PowerShell, and scripting in autoIT or VBS is something I rarely do, I experimented with creating a new Shell object.  Below is the code that I used for that:

 

#proxy Credentials
      $wshell = new-object -com wscript.shell
      $wshell.AppActivate("Windows Security")
      $wshell.sendkeys("{ENTER}")
      start-sleep -m 30
      $wshell.AppActivate("OneSign")
      $wshell.sendkeys("{ENTER}")
      start-sleep -m 30
      $wshell.AppActivate("Windows Security")
      $wshell.sendkeys("USERNAME")
      $wshell.sendkeys("{TAB}")
      $wshell.sendkeys("PASSWORD_OF_USER")
      start-sleep -m 30
      $wshell.sendkeys("{ENTER}") 

By utilizing $wshell = new-object -com wscript.shell, I was able to tap into .Net commands to interact with windows.  Now I could utilize some old VB Scripting code I had laying around from the past…

By utilizing $shell = New-Object -ComObject "Shell.Application", I was able to manipulate the Explorer.exe shell and minimize/maximize windows as I saw fit…

This was a very rewarding exercise.  Through this solution we (Coretek) were able to solve the client’s issues with the app, accommodate both teams (Desktop and PACs), simplify the end user experience, and best of all bring Windows 7 deployments back on schedule!

Send an Email from the Windows Command Prompt or Script, Pt II…

2017-07-27T00:01:03+00:00 November 14th, 2013|Uncategorized|

Following up on the earlier post, “Send an Email from the Windows Command Prompt or Script…

…While I’m somewhat picking up where I left off in Part 1, the situation in that earlier post had special requirements about how the email message had to be sent (controlled source, user interaction, etc.).  But what if you don’t have those requirements?  What if you simply want to send an email from a Windows workstation or Server? 

Well, in that case, simply use PowerShell.  Since version 2, PowerShell has included the Send-MailMessage cmdlet for relatively easy mail sending from almost any modern computer.

Recently, I was telling somebody how do use this method to send messages in a script, and demonstrating the input details such as specifying the SMTP relay server.  The person then asked me, “What if the SMTP server changes?”  Hmm…  Good point.   So I whipped up a few extra lines to work around that problem, and the person thought I should post it here.  Agreed!

Here is the script, put together as plainly as possible, with clearly named variables to help you understand what’s going on:

$MyRecipientEmailAddress = "Fake.Address@CoretekServices.com"
$MySenderEmailAddress = "JPavlov@YourLinuxGuy.com"
$MyRecipient = $MyRecipientEmailAddress.Split("@")
[0] $MyDestinationDomain = $MyRecipientEmailAddress.Split("@")[1] $MyMxRecords = Resolve-DnsName -Type MX -Name $MyDestinationDomain $MyMxRecord = $MyMxRecords[0].NameExchange $MyMessageSubject = "This is a test" $MyMessageBody = "This is the message. Thanks! - Jeremy" Send-MailMessage -To "$MyRecipientEmailAddress" -SmtpServer "$MyMxRecord" -Subject "$MyMessageSubject" -Body "$MyMessageBody" -From "$MySenderEmailAddress"

Remember, the trick is not really the standard options of the cmdlet, but grabbing the possibly-changing MX record for the relay.  This script will dynamically go and get the *current* first-listed MX record for the recipient, and just use that.

And I can almost hear you now, “…But Jeremy, aren’t you side-stepping the built-in fault-tolerance of the MX record?”  Yes, a bit; you can absolutely add a little more code to this and make it aware of the MX ranking, and roll through them and validate until successful.  Maybe I’ll do that in another post…

By the way, while it may not be obvious to you initially, note that I’m just specifying my recipient’s destination SMTP server as my -SmtpServer.  This *should* be fine in many/most cases.  The destination server should be glad to receive and forward the email to the end user that is a part of its own system.  However, some security protection may block this from happening, so be sure to know your destination first.  In my/our case, this was actually being used in an internal system to a friendly destination.  Your result may vary…

Now get out there and send those emails!

How to fix Ownerships and Inheritance on NTFS file systems, Pt. 2…

2017-07-27T00:01:03+00:00 September 18th, 2013|Uncategorized|

For background on this post, make sure to see Part 1, here

Picking up where we left off in Part 1, recall that I had a set of folders that were copied with original source permissions, and as a result, had broken permission “inheritance”.  The copy also brought over the various ownerships, which I was seeking to replace with the local “Administrators” group, according to standard practice of the customer.

So in Part 1, I had written a DOS batch script to loop through the folders and 1.) force down ownership in the new folder sub-structures (in order to follow company standard and be able to seize control of them), and 2.) re-apply inheritance of the administrative permissions from the folders above.  While I’d like to think I accomplished this swimmingly with my batch file, the truth is that it really needs to be in PowerShell in order to satisfy the needs of the team (future-proofing, portability, and such).

Let’s step through the PowerShell version now; but watch carefully because even though it is the same in principle as the DOS batch script in Part 1 (same enough to be worthy of comparison), it actually is a tad different in a few of the steps.

First, we clear the screen, set some variables, and clean up any files from the last run:

clear
$StartDate = date
Write-Host "Setting variables..."
$PARENTDRIVE = "S:"
$PARENTFOLDER = "Apps"
$PARENTPATH = "$PARENTDRIVE$PARENTFOLDER"
$LOCALPATH = "c:temp"
$TAKEOWNLOG = "$LOCALPATHtakeown-FixOwnerships.log"
$ICACLSLOG = "$LOCALPATHicacls-FixInheritance.log"
$ICACLSSUMMARYLOG = "$LOCALPATHicacls-FixInheritance-Summary.log"
Write-Host "Cleaning up log files from previous run..."
del $TAKEOWNLOG
del $ICACLSLOG

Now, with this PowerShell version of the script, I don’t need to write my lists out to a temp file for later processing (like I did with DOS in Part 1); I just dump it all into objects in memory.  Far more efficient!  Like so:

Write-Host "Creating Listing..."
$FolderListing = Get-ChildItem $PARENTPATH

Then, we hit the real work part of the script, where we loop through the folder listing, decend though and fix all the ownerships and inheritance.  This part is actually almost the same as the DOS batch script, actually, except that it’s more… um… awesomer:

Write-Host "Process listing..."
foreach ($FolderItem in $FolderListing)
{
  Write-Host "Fixing ownership: $PARENTPATH$FolderItem"
  Write-Output "Fixing ownership: $PARENTPATH$FolderItem" | Out-File $TAKEOWNLOG -append -encoding Default
  takeown /f $PARENTPATH$FolderItem /R /A /D Y  | Out-File $TAKEOWNLOG -append -encoding Default
  Write-Output "" | Out-File $TAKEOWNLOG -append -encoding Default
  #
  Write-Host "Fixing inheritance: $PARENTPATH$FolderItem"
  Write-Output "" | Out-File $ICACLSLOG -append -encoding Default
  Write-Output "Fixing inheritance: $PARENTPATH$FolderItem" | Out-File $ICACLSLOG -append -encoding Default
  ICACLS $PARENTPATH$FolderItem /inheritance:e | Out-File $ICACLSLOG -append -encoding Default
}

And finally, we create a summary log and create some closing comments before cleaning up:

Write-Host ""
Write-Host "Creating summary log..."
Select-String -pattern "Failed" $ICACLSLOG | Out-File $ICACLSSUMMARYLOG -encoding Default
Write-Host ""
$EndDate = date
Write-Host "Started: $StartDate"
Write-Host "Ended:   $EndDate"
Write-Host ""
Write-Host "...Complete!"

So that’s about it, really.  Note that I’m using the -encoding Default flag  at each Out-File so the file gets written in ANSI (on my system) instead of UniCode.   I don’t know about you, but I can’t stand dealing with UniCode files for text parsing and such.

And in case you prefer it in one contiguous list, here ya go:

clear
$StartDate = date
Write-Host "Setting variables..."
$PARENTDRIVE = "S:"
$PARENTFOLDER = "Apps"
$PARENTPATH = "$PARENTDRIVE$PARENTFOLDER"
$LOCALPATH = "c:temp"
$TAKEOWNLOG = "$LOCALPATHtakeown-FixOwnerships.log"
$ICACLSLOG = "$LOCALPATHicacls-FixInheritance.log"
$ICACLSSUMMARYLOG = "$LOCALPATHicacls-FixInheritance-Summary.log"
Write-Host "Cleaning up log files from previous run..."
del $TAKEOWNLOG
del $ICACLSLOG
Write-Host "Creating Listing..."
$FolderListing = Get-ChildItem $PARENTPATH
Write-Host "Process listing..."
foreach ($FolderItem in $FolderListing)
{
  Write-Host "Fixing ownership: $PARENTPATH$FolderItem"
  Write-Output "Fixing ownership: $PARENTPATH$FolderItem" | Out-File $TAKEOWNLOG -append -encoding Default
  takeown /f $PARENTPATH$FolderItem /R /A /D Y  | Out-File $TAKEOWNLOG -append -encoding Default
  Write-Output "" | Out-File $TAKEOWNLOG -append -encoding Default
  #
  Write-Host "Fixing inheritance: $PARENTPATH$FolderItem"
  Write-Output "" | Out-File $ICACLSLOG -append -encoding Default
  Write-Output "Fixing inheritance: $PARENTPATH$FolderItem" | Out-File $ICACLSLOG -append -encoding Default
  ICACLS $PARENTPATH$FolderItem /inheritance:e | Out-File $ICACLSLOG -append -encoding Default
}
Write-Host ""
Write-Host "Creating summary log..."
Select-String -pattern "Failed" $ICACLSLOG | Out-File $ICACLSSUMMARYLOG -encoding Default
Write-Host ""
$EndDate = date
Write-Host "Started: $StartDate"
Write-Host "Ended:   $EndDate"
Write-Host ""
Write-Host "...Complete!"

Enjoy!

 

 

Load More Posts

Fatal error: Uncaught exception 'GuzzleHttp\Exception\ClientException' with message 'Client error: `POST https://dc.services.visualstudio.com/v2/track` resulted in a `400 Invalid instrumentation key` response: {"itemsReceived":1,"itemsAccepted":0,"errors":[{"index":0,"statusCode":400,"message":"Invalid instrumentation key"}]} ' in /home/coretek/public_html/wp-content/plugins/application-insights/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:113 Stack trace: #0 /home/coretek/public_html/wp-content/plugins/application-insights/vendor/guzzlehttp/guzzle/src/Middleware.php(66): GuzzleHttp\Exception\RequestException::create(Object(GuzzleHttp\Psr7\Request), Object(GuzzleHttp\Psr7\Response)) #1 /home/coretek/public_html/wp-content/plugins/application-insights/vendor/guzzlehttp/promises/src/Promise.php(203): GuzzleHttp\Middleware::GuzzleHttp\{closure}(Object(GuzzleHttp\Psr7\Response)) #2 /home/coretek/public_html/wp-content/plugins/application-insights/vendor/guzzlehttp/promises/src/Promise.php(156): GuzzleHttp\Promi in /home/coretek/public_html/wp-content/plugins/application-insights/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php on line 113