tag:blogger.com,1999:blog-89174186434831777622024-03-13T12:09:06.219+01:00Peter's Tech NotesMainly small hacks or solutions for problems I run into and can't find elsewhere.
Most posts are related to Microsoft Exchange, PowerShell and Tasker. Looking forward to find a use for Raspberry Pi shortly.Peterhttp://www.blogger.com/profile/00234062535095025694noreply@blogger.comBlogger8125tag:blogger.com,1999:blog-8917418643483177762.post-831427485654703442015-02-12T07:38:00.000+01:002015-02-12T07:50:56.186+01:00Use Google Sheets cell content in script<br />
<div style="border: 0px; color: #383838; font-family: gotham, helvetica, arial, sans-serif; font-size: 14px; line-height: 1.571428em; margin: 0px; padding: 0px;">
Wouldn't it be nice to collect data using a Google Sheets Form and be able to get each cell value from a script on your phone or computer? It can be done.</div>
<div style="border: 0px; color: #383838; font-family: gotham, helvetica, arial, sans-serif; font-size: 14px; line-height: 1.571428em; margin: 0px; padding: 0px;">
<br /></div>
<div style="border: 0px; color: #383838; font-family: gotham, helvetica, arial, sans-serif; font-size: 14px; line-height: 1.571428em; margin: 0px; padding: 0px;">
I'm assuming the data you need for your script is already in a Google Sheet. It could be collected using a form or similar. To get unauthenticated access to a Google Sheet it needs to be published. Either publish the sheet containing the data or create a and publish new Google Sheet to hold only the data needed for the script. Import the data to that new sheet using =IMPORTRANGE().</div>
<div style="border: 0px; color: #383838; font-family: gotham, helvetica, arial, sans-serif; font-size: 14px; line-height: 1.571428em; margin: 0px; padding: 0px;">
<br clear="none" /></div>
<div style="border: 0px; color: #383838; font-family: gotham, helvetica, arial, sans-serif; font-size: 14px; line-height: 1.571428em; margin: 0px; padding: 0px;">
To get the URL for the published sheet, have a look at this page: <a data-mce-href="https://developers.google.com/gdata/samples/spreadsheet_sample" href="https://developers.google.com/gdata/samples/spreadsheet_sample" shape="rect" style="border: 0px; color: #047ac6; cursor: pointer; line-height: 1.571428em; margin: 0px; padding: 0px;" target="_blank">https://developers.google.com/gdata/samples/spreadsheet_sample</a>. Basically you just need the key for the sheet.</div>
<div style="border: 0px; color: #383838; font-family: gotham, helvetica, arial, sans-serif; font-size: 14px; line-height: 1.571428em; margin: 0px; padding: 0px;">
<br clear="none" /></div>
<div style="border: 0px; color: #383838; font-family: gotham, helvetica, arial, sans-serif; font-size: 14px; line-height: 1.571428em; margin: 0px; padding: 0px;">
The published sheet URL looks something like this:</div>
<div style="border: 0px; color: #383838; font-family: gotham, helvetica, arial, sans-serif; font-size: 14px; line-height: 1.571428em; margin: 0px; padding: 0px;">
<a data-mce-href="https://docs.google.com/spreadsheets/d/<key>/pubhtml?gid=0&single=true" href="https://docs.google.com/spreadsheets/d/%3Ckey%3E/pubhtml?gid=0&single=true" shape="rect" style="border: 0px; color: #047ac6; cursor: pointer; line-height: 1.571428em; margin: 0px; padding: 0px;" target="_blank">https://docs.google.com/spreadsheets/d/<key>/pubhtml?gid=0&single=true</a><br />
<br clear="none" />
<span style="line-height: 1.571428em;">After some experimentation with various URL formats I got cell A1 using this URL:</span><br />
<a data-mce-href="https://spreadsheets.google.com/feeds/cells/<key>/od6/public/basic/R1C1" href="https://spreadsheets.google.com/feeds/cells/%3Ckey%3E/od6/public/basic/R1C1" shape="rect" style="border: 0px; color: #047ac6; cursor: pointer; line-height: 1.571428em; margin: 0px; padding: 0px;" target="_blank">https://spreadsheets.google.com/feeds/cells/<key>/od6/public/basic/R1C1</a></div>
<div style="border: 0px; color: #383838; font-family: gotham, helvetica, arial, sans-serif; font-size: 14px; line-height: 1.571428em; margin: 0px; padding: 0px;">
<br clear="none" /></div>
<div style="border: 0px; color: #383838; font-family: gotham, helvetica, arial, sans-serif; font-size: 14px; line-height: 1.571428em; margin: 0px; padding: 0px;">
Cell C2 would look like this:</div>
<div style="border: 0px; color: #383838; font-family: gotham, helvetica, arial, sans-serif; font-size: 14px; line-height: 1.571428em; margin: 0px; padding: 0px;">
<a data-mce-href="https://spreadsheets.google.com/feeds/cells/<key>/od6/public/basic/R2C3" href="https://spreadsheets.google.com/feeds/cells/%3Ckey%3E/od6/public/basic/R2C3" shape="rect" style="border: 0px; color: #047ac6; cursor: pointer; line-height: 1.571428em; margin: 0px; padding: 0px;" target="_blank">https://spreadsheets.google.com/feeds/cells/<key>/od6/public/basic/R2C3</a></div>
<div style="border: 0px; color: #383838; font-family: gotham, helvetica, arial, sans-serif; font-size: 14px; line-height: 1.571428em; margin: 0px; padding: 0px;">
<br clear="none" /></div>
<div style="border: 0px; margin: 0px; padding: 0px;">
<div style="color: #383838; font-family: gotham, helvetica, arial, sans-serif; font-size: 14px; line-height: 1.571428em;">
OK, on to the content. Below is the content I get when requesting cell R1C1. The actual data is between the tags <content type='text'> and </content></div>
<div style="color: #383838; font-family: gotham, helvetica, arial, sans-serif; font-size: 14px; line-height: 1.571428em;">
<br /></div>
<blockquote class="tr_bq">
<span style="color: #383838; font-family: Courier New, Courier, monospace;"><span style="background-color: white; line-height: 21.9999923706055px;"><?xml version='1.0' encoding='UTF-8'?><entry xmlns='http://www.w3.org/2005/Atom' xmlns:batch='http://schemas.google.com/gdata/batch' xmlns:gs='http://schemas.google.com/spreadsheets/2006'><id>https://spreadsheets.google.com/feeds/cells/<key>/od6/public/basic/R1C1</id><updated>2014-12-12T07:35:19.026Z</updated><category scheme='http://schemas.google.com/spreadsheets/2006' term='http://schemas.google.com/spreadsheets/2006#cell'/><title type='text'>A1</title><content type='text'>2</content><link rel='self' type='application/atom+xml' href='https://spreadsheets.google.com/feeds/cells/<key>/od6/public/basic/R1C1'/></entry></span></span></blockquote>
<div style="color: #383838; font-family: gotham, helvetica, arial, sans-serif; font-size: 14px; line-height: 1.571428em;">
<br /></div>
</div>
<div data-mce-style="text-align: left;" style="border: 0px; color: #383838; font-family: gotham, helvetica, arial, sans-serif; font-size: 14px; line-height: 1.571428em; margin: 0px; padding: 0px;">
<pre style="border: 0px; font-family: Monaco, Courier, monospace; line-height: 1.571428em; padding: 0px;" xml:space="preserve"><span data-mce-style="font-family: gotham, helvetica, sans-serif;" style="font-family: gotham, helvetica, sans-serif; line-height: 1.571428em;">We just need to split the content on <content type='text'> and then split the second part again on </content>. The cell data is in the first part of the second split.
PowerShell example:
<pre><code class="powershell">$CellA1 = Invoke-WebRequest -UseBasicParsing -Uri https://spreadsheets.google.com/feeds/cells/1DzK0hnq9bexu6h1ryZzPP6-WWk55IEx0xZrtFKK6UZI/od6/public/basic/R1C1
$Value = (($CellA1 -split "<content type=.text.>") -split "</content")[1]</code></pre>
Tasker example:
<pre><code class="html"><span style="line-height: 1.571428em;">GetValueFromSheet (4)</span>
<span style="line-height: 1.571428em;">A1: HTTP Get [ Server:Port:</span><a data-mce-href="https://spreadsheets.google.com/" href="https://spreadsheets.google.com/" style="border: 0px; color: #047ac6; cursor: pointer; line-height: 1.571428em; margin: 0px; padding: 0px;" target="_blank">https://spreadsheets.google.com</a><span style="line-height: 1.571428em;">/ Path:feeds/cells/<key>/od6/public/basic/R1C1 Attributes: Cookies: User Agent: Timeout:10 Mime Type: Output File: Trust Any Certificate:Off ] </span>
<span style="line-height: 1.571428em;">A2: Variable Split [ Name:%HTTPD Splitter:<content type='text'> Delete Base:On ] </span>
<span style="line-height: 1.571428em;">A3: Variable Split [ Name:%HTTPD2 Splitter:</content> Delete Base:On ] </span>
<span style="line-height: 1.571428em;">A4: Variable Set [ Name:%Value To:%HTTPD21 Do Maths:Off Append:Off ] </span>
</code></pre>
The content of A1 in the Google Sheet is now in Tasker variable %Value.
You could use this to trigger other Tasker tasks or to present that value on a Zooper Widget, or send it to Pushover. I use it for a few things, and might write a more detailed end-to-end post on that.</span></pre>
</div>Peterhttp://www.blogger.com/profile/00234062535095025694noreply@blogger.com3tag:blogger.com,1999:blog-8917418643483177762.post-25464181902156991332015-02-11T13:43:00.001+01:002015-02-11T14:09:14.953+01:00Change Exchange primary email address to lower caseBy default Microsoft Exchange creates email addresses on the form First.Last@domain.com. If you change the email address policy to use lowercase, the existing email addresses are not updated to reflect that change.<br />
<br />
It doesn't work to change the primary SMTP address to lower case right away, since email addresses are basically case insensitive. When you set a new primary SMTP address, the old address is kept as an alias email address. Exchange can't set a new primary email address since the same address already exists as an alias. More or less, you get the picture.<br />
<br />
I created the following script to make the change<br />
<br />
<pre><code class="powershell">
# Get all mailboxes in the users OU (select the OU for which you want to change to lower case
$Mailboxes = Get-Mailbox -OrganizationalUnit "OU=Users,DC=domain,DC=com" -ResultSize Unlimited
# Loop through all mailboxes
ForEach ($Mailbox in $Mailboxes)
{
# Turn off email address policy
Set-Mailbox -Identity $Mailbox.Identity -EmailAddressPolicyEnabled $false
# Set a temporary primary email address
Set-Mailbox -Identity $Mailbox.Identity -PrimarySmtpAddress "dummy@domain.com"
# Remove the old primary address which is now a standard email address connected to the mailbox
Set-Mailbox -Identity $Mailbox.Identity -EmailAddresses @{Remove=$Mailbox.PrimarySmtpAddress}
# Convert the old primary address to lowercase
$lowercasesmtp = $Mailbox.PrimarySmtpAddress.ToLower()
# Set the lowercase email address as primary
Set-Mailbox -Identity $Mailbox.Identity -PrimarySmtpAddress $lowercasesmtp
# Remove the temp primary address
Set-Mailbox -Identity $Mailbox.Identity -EmailAddresses @{Remove='dummy@domain.com'}
# Turn on the address policy
Set-Mailbox -Identity $Mailbox.Identity -EmailAddressPolicyEnabled $true
# Check the result
Get-Mailbox -Identity $Mailbox.Identity | select Name, *SMTP*, Email*
}</code></pre>
Peterhttp://www.blogger.com/profile/00234062535095025694noreply@blogger.com5tag:blogger.com,1999:blog-8917418643483177762.post-74736449800067564822015-01-21T10:57:00.000+01:002015-01-21T13:19:49.407+01:00Exchange 2013 mailbox quota usage and size reportIn Exchange 2013 it can be a bit hard to find mailboxes that are close to their quota limits. You can see it in the Exchange Admin Center, but that is a tedious task if you want to check all mailboxes.<br />
You can also wait for the users to contact you when they get a quota warning, or when they no longer can send email. That's a bit late.<br />
With PowerShell you can easily find out the mailbox size, but the quota limit is either Unlimited, which means that the mailbox database defaults are used, or it can be set at a certain limit.<br />
<br />
Find the mailbox quota<br />
<pre><code class="powershell">get-mailbox mailbox | select-object DisplayName, ProhibitSendQuota, ProhibitSendReceiveQuota
DisplayName ProhibitSendQuota ProhibitSendReceiveQuota
----------- ----------------- ------------------------
User Name Unlimited Unlimited
</code></pre>
<br />
Find the mailbox size and database quota<br />
<pre><code class="powershell">Get-MailboxStatistics -identity mailbox | select-object Displayname,TotalItemSize,TotalDeletedItemSize,DatabaseIssueWarningQuota,DatabaseProhibitSendQuota
DisplayName : User Name
TotalItemSize : 1.125 GB (1,208,281,527 bytes)
TotalDeletedItemSize : 24.14 MB (25,309,210 bytes)
DatabaseIssueWarningQuota : 5 GB (5,368,709,120 bytes)
DatabaseProhibitSendQuota : 6 GB (6,442,450,944 bytes)
</code></pre>
<br />
<br />
So, the numbers are all there, just not in a nice format...<br />
<br />
To make a long story short - here's a PowerShell script that will output all mailboxes with a quota usage over 80%<br />
<br />
<pre><code class="powershell"><#
.SYNOPSIS
TGet-MailboxSizeQuota.ps1 returns all mailboxes above a certain quota (ProhibitSendQuota) usage.
.DESCRIPTION
TGet-MailboxSizeQuota.ps1 returns all mailboxes with a quota usage of 80% and above.
If you want to check for another quota limit, pass the percentage as a parameter.
TGet-MailboxSizeQuota.ps1 <percentage>
.EXAMPLE
TGet-MailboxSizeQuota.ps1
The above command will return all mailboxes with a quota usage of 80% and above
.EXAMPLE
TGet-MailboxSizeQuota.ps1 85
The above command will return all mailboxes with a quota usage of 85% and above
.NOTES
Author: Peter Haake
Date: 2015-01-20
#>
#
# Load the Exchange Management Module
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn
# Make sure en-us locale is used no matter what the server/user has configured
# Keep this section if you output decimal numbers
# Slightly modified from From http://occasionalutility.blogspot.com.au/2014/03/everyday-powershell-part-17-using-new.html
[System.Reflection.Assembly]::LoadWithPartialName("System.Threading")>$null
[System.Reflection.Assembly]::LoadWithPartialName("System.Globalization")>$null
[System.Threading.Thread]::CurrentThread.CurrentCulture = [System.Globalization.CultureInfo]::CreateSpecificCulture("en-us")
# Set quotalimit to the first parameter passed. If no parameter is passed, set it at 80%
if ([INT]$args[0] -gt "") {
$quotalimit = [INT]$args[0]
}
else {
$quotalimit = 80
}
# Get all mailboxes
$Mailboxes = @(Get-Mailbox -ResultSize Unlimited | select-object DisplayName, Identity, ProhibitSendQuota, ProhibitSendReceiveQuota)
# Clear the report object variable
$Report =@()
# Loop through all mailboxes
foreach ($usr_mailbox in $Mailboxes)
{
# Get statistics for all mailboxes
$usr_mailboxstats = Get-MailboxStatistics -identity $usr_mailbox.Identity | select-object Displayname,Identity,Database,TotalItemSize,TotalDeletedItemSize,DatabaseIssueWarningQuota,DatabaseProhibitSendQuota
#Convert TotalItemSize to INT64 and remove crap (looks like this initially "1.123 GB (1,205,513,370 bytes)" and comes out as a numeric 1205513370)
[int64]$usr_mailboxstats_totalitemsize = [convert]::ToInt64(((($usr_mailboxstats.TotalItemSize.ToString().split("(")[-1]).split(")")[0]).split(" ")[0]-replace '[,]',''))
#Convert TotalDeletedItemSize to INT and remove crap (looks like this initially "1.123 GB (1,205,513,370 bytes)" and comes out as a numeric 1205513370)
[int64]$usr_mailboxstats_totaldeleteditemsize = [convert]::ToInt64(((($usr_mailboxstats.TotalDeletedItemSize.ToString().split("(")[-1]).split(")")[0]).split(" ")[0]-replace '[,]',''))
# If the mailbox quota is Unlimited, then the database defaults are used.
if ($usr_mailbox.ProhibitSendQuota -eq "Unlimited") {
# Get quota from Database
[INT64]$usr_quota = [convert]::ToInt64(((($usr_mailboxstats.DatabaseProhibitSendQuota.ToString().split("(")[-1]).split(")")[0]).split(" ")[0]-replace '[,]',''))
}
else {
# Get quota from user mailbox
[INT64]$usr_quota = [convert]::ToInt64(((($usr_mailbox.ProhibitSendQuota.ToString().split("(")[-1]).split(")")[0]).split(" ")[0]-replace '[,]',''))
}
# Calculate the quota percentage
$usr_quota_percentage = [INT]((($usr_mailboxstats_totalitemsize + $usr_mailboxstats_totaldeleteditemsize) / $usr_quota)*100)
# Add to report object
if ($usr_quota_percentage -ge $quotalimit) {
$usr_reportObject = New-Object PSObject
$usr_reportObject | Add-Member -MemberType NoteProperty -Name "DisplayName" -Value $usr_mailboxstats.DisplayName
$usr_reportObject | Add-Member -MemberType NoteProperty -Name "TotalItemSize" -Value $usr_mailboxstats_totalitemsize
$usr_reportObject | Add-Member -MemberType NoteProperty -Name "TotalDeletedItemSize" -Value $usr_mailboxstats_totaldeleteditemsize
$usr_reportObject | Add-Member -MemberType NoteProperty -Name "ProhibitSendQuota" -Value $usr_quota
$usr_reportObject | Add-Member -MemberType NoteProperty -Name "QuotaPercent" -Value $usr_quota_percentage
$report += $usr_reportObject
}
}
# Output the report, sorted with the highest quota percentage at the top
$Report | Sort-Object QuotaPercent -Descending
</percentage></code></pre>
<br />
Output looks something like this<br />
<pre><code class="powershell">
DisplayName TotalItemSize TotalDeletedItemSize ProhibitSendQuota QuotaPercent
----------- ------------- -------------------- ----------------- ------------
User Name 8316860830 49373170 9663676416 87
Second User 14581624515 17277483 17179869184 85
Third Person 5472939739 15151742 6442450944 85
</code></pre>
<br />
<h4>
Send the output from the script as an email</h4>
If you want to schedule the script to run every week or so, it might be convenient to have the output sent to you in an email. Create another script, and call TGet-MailboxSizeQuota.ps1 from that as below:<br />
<pre><code class="powershell">
Send-MailMessage -to email@domain.com -Subject "Quota Report" -SmtpServer mail.server.FQDN -From from@domain.com -Body (C:\Scripts\TGet-MailboxSizeQuota.ps1 | ft | Out-String)
</code></pre>
<br />
This can easily be added as a scheduled task. Just make sure to run the task under a user account that has enough rights in Exchange.Peterhttp://www.blogger.com/profile/00234062535095025694noreply@blogger.com1tag:blogger.com,1999:blog-8917418643483177762.post-5562796143472350722014-12-05T10:09:00.002+01:002015-01-21T13:02:32.384+01:00Getting New-MailboxExportRequest work with date variables in ContentFilter<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-Avha1pV4aa0/VIF4OmY2qPI/AAAAAAAAD6o/aA_qD41g2I4/s1600/P5_400x225_Exchange-Online-Plan-2.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-Avha1pV4aa0/VIF4OmY2qPI/AAAAAAAAD6o/aA_qD41g2I4/s1600/P5_400x225_Exchange-Online-Plan-2.gif" height="180" width="320" /></a></div>
<br />
The following script exported the full mailbox, ignoring the date range in ContentFilter. I couldn't figure it out. Found a lot of people with the same problem. </div>
<pre><code class="powershell">
$StartDate = (Get-Date).AddDays(-1).Date
$EndDate = (Get-Date).Date
$FilePath = "\\server\export.pst"
New-MailboxExportRequest -Mailbox peter -Name TestExport -FilePath $FilePath -ContentFilter {(Received -gt $StartDate) -and (Received -lt $EndDate)}
</code></pre>
<div>
I finally found a solution here: <a href="http://occasionalutility.blogspot.com.au/2014/03/everyday-powershell-part-17-using-new.html">http://occasionalutility.blogspot.com.au/2014/03/everyday-powershell-part-17-using-new.html</a> Turns out it will only accept dates in US formats, and since I'm in Sweden it just failed.</div>
<div>
<br /></div>
<div>
The working script looks like this:</div>
<pre><code class="powershell">
[System.Reflection.Assembly]::LoadWithPartialName("System.Threading")
[System.Reflection.Assembly]::LoadWithPartialName("System.Globalization")
[System.Threading.Thread]::CurrentThread.CurrentCulture = [System.Globalization.CultureInfo]::CreateSpecificCulture("en-us")
$StartDate = (Get-Date).AddDays(-1).Date
$EndDate = (Get-Date).Date
$FilePath = "\\server\petero-"+(Get-Date).AddDays(-1).ToString("yyyy-MM-dd")+".pst"
$filter = "(Received -gt '"+$StartDate+"') -and (Received -lt '"+$EndDate+"')"
New-MailboxExportRequest -Name TestExport -Mailbox peter -ContentFilter $filter -FilePath $FilePath
</code></pre>Peterhttp://www.blogger.com/profile/00234062535095025694noreply@blogger.com0tag:blogger.com,1999:blog-8917418643483177762.post-37477582545907236982013-03-28T07:12:00.002+01:002013-03-28T09:23:37.846+01:00Find your phone with Tasker and Pushover<div class="separator" style="clear: both; text-align: center;">
<a href="http://tasker.dinglisch.net/" target="_blank"><img border="0" src="http://2.bp.blogspot.com/-gi62SVfHqIo/UVPdhdqiihI/AAAAAAAAAFI/pUxfGKw9Fjo/s1600/Tasker.png" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://bit.ly/11KE8rW" target="_blank"><img border="0" height="67" src="http://3.bp.blogspot.com/-1-SH0Kdi-M0/UVPdhr16aoI/AAAAAAAAAFM/yEoQ5v5Njnc/s320/pushover-logo.png" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<a href="http://bit.ly/13zhJmp" target="_blank">Tasker</a> is a tool to automate almost anything on Android. I use it to adjust volumes on a schedule, turn off pattern lock screen at home, etc. I will write more posts about Tasker, but if you want to try it out there's a 7-day trial version on the <a href="http://bit.ly/13zhJmp" target="_blank">Tasker site</a>, and a full, paid version on <a href="http://bit.ly/13zicVO" target="_blank">Play Store</a>. I can recommend the <a href="http://www.pocketables.com/tag/beginners-guide-to-tasker" target="_blank">Pocketables Beginner's Guide to Tasker</a> series, the <a href="http://tasker.dinglisch.net/userguide/en/" target="_blank">Userguide on Taskers web site</a> and this <a href="http://tasker.wikidot.com/" target="_blank">Tasker Wiki</a><br />
<br />
I already mentioned <a href="http://bit.ly/11KE8rW" target="_blank">Pushover</a> in a <a href="http://blog.haake.nu/2013/03/get-notified-when-your-computer-reboots.html" target="_blank">previous post</a>, but essentially it's a tool to send notification to mobile devices (Android and iOS).<br />
<br />
I wanted a way to locate my mobile phone in case it's lost. There are many apps that can do this already, but with Tasker you can do it yourself. I didn't even have to figure out how to do it myself, as a good recipe is already available on a <a href="http://tasker.wikidot.com/locatephone" target="_blank">Tasker Wiki</a>. There are some variants on that site and I ended up with the tasker code below.<br />
To find your phone, send a text message to your lost from from any other mobile phone with <your keyword> in the message. Tasker will trigger, get the phone location using any of the methods available (GPS or WiFi positioning) and send back a text message with a Google Maps URL with your lost phones position mapped out.<br />
<br />
Tasker Profile<br />
<blockquote class="tr_bq">
<span style="background-color: #eeeeee;">Profile: LocateSMS (2)</span><br />
<span style="background-color: #eeeeee;">Event: Received Text [ Type:Any Sender:* Content:<your keyword> ]</span><br />
<span style="background-color: #eeeeee;">Enter: LocationPushover (3)</span></blockquote>
<div>
<br />
Tasker Task<br />
<blockquote class="tr_bq">
<span style="background-color: #eeeeee;">LocationPushover (3)</span><br />
<span style="background-color: #eeeeee;">A1: Get Location [ Source:Any Timeout (Seconds):120 Continue Task Immediately:Off Keep Tracking:Off ]</span><br />
<span style="background-color: #eeeeee;">A2: Variable Set [ Name:%LOCATION To:%LOCN Do Maths:Off Append:Off ] If [ %LOC ! Set ]</span><br />
<span style="background-color: #eeeeee;">A3: Variable Set [ Name:%LOCATION To:%LOC Do Maths:Off Append:Off ] If [ %LOC Is Set ]</span><br />
<span style="background-color: #eeeeee;">A4: Send SMS [ Number:%SMSRF Message:http://maps.google.com/maps?q=%LOCATION Store In Messaging App:Off ]</span><br />
<span style="background-color: #eeeeee;">A5: Variable Clear [ Name:%LOCATION Pattern Matching:Off ] </span></blockquote>
</div>
<div>
<br />
<span style="font-family: inherit;"><span style="font-family: inherit;">This is nice, but since I've started to use Pus</span>hover for notifications I wanted to try that out as well. Reading up on the <a href="https://pushover.net/api" target="_blank">Pushover API</a> I </span>figured<span style="font-family: inherit;"> the easiest way is to do a HTTP Post from Tasker with a properly formatted Path. Since I want to send a URL in the notification message I need to URL encode it, otherwise Pushover API would try to interpret the /, ? and & as part of the API URI. I URL encoded the Google Maps </span><br />
<br />
URL part and ended up with a new step four in the Tasker Task.<br />
<br />
<blockquote class="tr_bq">
<span style="background-color: #eeeeee;">A4: HTTP Post [ Server:Port:https://api.pushover.net Path:/1/messages.json?user=<user token>&token=<app token>&title=Phone+location&message=http%3A%2F%2Fmaps.google.com%2Fmaps%3Fq%3D%LOCATION Data / File: Cookies: Timeout:10 Content Type:application/x-www-form-urlencoded Output File: ] </span></blockquote>
URL Encoding is easy. A good guide is available at the <a href="http://www.w3schools.com/tags/ref_urlencode.asp">w3schools.com website</a>. This URL:<br />
<blockquote class="tr_bq">
<span style="background-color: #eeeeee;">http://maps.google.com/maps?q=%LOCATION</span></blockquote>
is turned into this:<br />
<blockquote class="tr_bq">
<span style="background-color: #eeeeee;">http%3A%2F%2Fmaps.google.com%2Fmaps%3Fq%3D%LOCATION</span></blockquote>
<br />
In addition to the Tasker script, I created a new Pushover application, added a Google Maps icon and that was it. When I send a text with my keyword I get the following Pushover notification on all my devices.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-b1dhAIBDjsE/UVP9JT-a3UI/AAAAAAAAAFw/xN_45OXifao/s1600/Screenshot_2013-03-28-09-11-57.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="186" src="http://1.bp.blogspot.com/-b1dhAIBDjsE/UVP9JT-a3UI/AAAAAAAAAFw/xN_45OXifao/s320/Screenshot_2013-03-28-09-11-57.png" width="320" /></a></div>
<br />
If you want to use the code above, you just need to change <your keyword> to a keyword of your choice. This is the word you need to text to your lost phone to trigger the Tasker Profile and Task. In the code you also need to replace <user token> and <app token> if you want to use Pushover.</div>
Peterhttp://www.blogger.com/profile/00234062535095025694noreply@blogger.com0tag:blogger.com,1999:blog-8917418643483177762.post-67640356368882039062013-03-27T08:16:00.000+01:002013-03-28T09:22:24.955+01:00Get notified when your computer reboots using Pushover<div class="separator" style="clear: both; text-align: center;">
<a href="http://bit.ly/11KE8rW" target="_blank"><img border="0" height="67" src="http://1.bp.blogspot.com/-M1jEDqgg0T8/UVKce3Kqa6I/AAAAAAAAAEw/JpQsa_j87WI/s320/pushover-logo.png" width="320" /></a></div>
<br />
<a href="http://bit.ly/11KE8rW" target="_blank">Pushover</a> is a platform for sending and receiving push notifications to mobile devices (Android and iOS). Pushover is free, but requires the installation of a paid app on your Android or iOS device. After you set up your account on Pushover you get a user token that is used to identify you as the sender of a notification.<br />
To send notifications, create a new application on the Pushover site. Give it a name, select type and upload an icon. After the application is registered you get an application token that identifies your application.<br />
<br />
OK, so I wanted a notification sent to my phone whenever my computer restarted. Since it's a Windows 8 computer I decided to go for PowerShell 3.0 and created the following script:<br />
<blockquote class="tr_bq">
<span style="background-color: #eeeeee;">$uri = "https://api.pushover.net/1/messages.json"</span><br />
<span style="background-color: #eeeeee;">$parameters = @{</span><br />
<span style="background-color: #eeeeee;"> token = "<app token>"</span><br />
<span style="background-color: #eeeeee;"> user = "<user token>"</span><br />
<span style="background-color: #eeeeee;"> title = "Reboot"</span><br />
<span style="background-color: #eeeeee;"> message = "Your computer just rebooted"</span><br />
<span style="background-color: #eeeeee;">}</span><br />
<span style="background-color: #eeeeee;">$parameters | Invoke-RestMethod -Uri $uri -Method Post</span></blockquote>
Nothing special about the script, basically it's a slight modification of an example script found on the <a href="http://bit.ly/11KHb3s" target="_blank">Pushover FAQ</a>. Just replace <app token> and <user token> with your own tokens.<br />
<br />
Next, I need to have the script run when the computer starts, and run before anyone logs on. That's the point, right, if I'm at the computer I don't need a notification telling me the computer restarted.<br />
Run the Local Group Policy Editor (gpedit.msc) tool as administrator and drill down to Local Computer Policy -> Computer Configuration -> Windows Settings -> Scripts and open Startup.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/--xXS1Pr9zMU/UVKbnFMXYZI/AAAAAAAAAEo/Yb-t0kEIaRk/s1600/gpedit.msc.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="223" src="http://3.bp.blogspot.com/--xXS1Pr9zMU/UVKbnFMXYZI/AAAAAAAAAEo/Yb-t0kEIaRk/s320/gpedit.msc.PNG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Go to the PowerShell Scripts tab and click Add. Click Browse next to Script Name and locate your script. Click OK, OK and then close the policy editor.<br />
<br />
All done!Peterhttp://www.blogger.com/profile/00234062535095025694noreply@blogger.com1tag:blogger.com,1999:blog-8917418643483177762.post-31229143680120597202013-03-25T14:04:00.000+01:002013-03-25T14:17:45.579+01:00PowerShell Books<div class="separator" style="clear: both; text-align: center;">
<a href="http://bit.ly/11Cf4Dw" target="_blank"><img border="0" height="71" src="http://3.bp.blogspot.com/-CJm8AImnhAw/UVBOSdbSwGI/AAAAAAAAAEU/Jm6uWxmUf8M/s320/PowerShell+Book+Guide.png" width="320" /></a></div>
<br />
Just found PowerShellBooks.com (<a href="http://bit.ly/11Cf4Dw">http://bit.ly/11Cf4Dw</a>) that lists a number of PowerShell books, and also provides three books for free download in PDF format.Peterhttp://www.blogger.com/profile/00234062535095025694noreply@blogger.com0tag:blogger.com,1999:blog-8917418643483177762.post-18195494165167163192013-03-14T09:09:00.000+01:002013-03-25T14:15:26.234+01:00Free Microsoft ePub and PDF BooksWhen setting up a Lync 2013 server I came across "<a href="http://bit.ly/13UtwL7" target="_blank">Microsoft Lync Server 2013 Step by Step for Anyone</a>" eBook by Matt Landis available for free on the Microsft TechNet site.<br />
<div>
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://bit.ly/13UtwL7" target="_blank"><img alt="Microsoft Lync Server 2013 Step By Step for Anyone eBook cover" border="0" height="200" src="http://2.bp.blogspot.com/-daSswgBgw_w/UUGSbn4HRfI/AAAAAAAAAD0/pPref539CPE/s200/Microsoft+Lync+Server+2013+Step+By+Step+for+Anyone+eBook+cover.png" title="Microsoft Lync Server 2013 Step By Step for Anyone eBook" width="154" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br /></div>
<div>
Turns out, there are a lot of books available for free in various formats from the <a href="http://bit.ly/13Ut6V1" target="_blank">TechNet eBook Gallery</a> (scroll down) and from <a href="http://bit.ly/13Uw0t0" target="_blank">Microsoft Press Blog</a>. I haven't yet found a complete listing, and maybe one doesn't exist.</div>
Peterhttp://www.blogger.com/profile/00234062535095025694noreply@blogger.com0