Archive for April 2011
WordPress and PowerShell Code. The Second Try
Last week I complained about how it is not easy to post Powershell code here. The letter of my dissatisfaction has been sent to and the answer was received from the WordPress support.
As a first step of our efforts to improve the code coloration was the question about what is wrong and what I’ve wanted. Of course, I assured the support specialist that I’ll provide so many examples of code that they will be able to polish publishing if they want to. That time the code sample appeared as on the following figure:
This post is the next step. I copy-pasted the WordPress code from my previous post on this topic to LibreOffice Writer 3.3, marked the most of significant blocks of code with several colors and put it back to WordPress page as an HTML.
Below is what I’d expect I might have had in my blog when I use the ‘sourcecode’ tag:
cls
#region WordPress posting code test
#this is a test of Powershell code coloring
[string]$stringVar1 = “string 1”;
[string]$private:stringVar2 = ‘string 2’;
[string]$script:stringVar3=
@’
string data
‘@
[scriptblock]$global:sb = {{Write-Host scriptblock}.Invoke();};
function
write1{Write-Host $stringVar1;}
function private:write2
{param([string]$str2 = ”)Write-Host $str2;}
function script:write3
#this is a function
{
Write-Host $script:stringVar3;
}
function global:Print-SB
{
<#
.SYNOPSIS
This is a code coloring test.
.DESCRIPTION
This test function represents an advanced Powershell function syntax.
.PARAMETER Param
Demonstrates how a scriptblock can be passed as a reference.
.EXAMPLE
PS C:\> Print-SB ([ref]$sb)
#>
[CmdletBinding()]
param(
[Parameter(Position=0, Mandatory=$true)]
[ref]$Param
)
Begin{}
Process{$Param.Value.Invoke()}
End{}
}
write1
private:write2 $private:stringVar2;
script:write3
Print-SB ([ref]$global:sb)
#endregion WordPress posting code test
I divided all the sample code into several meaningful groups. Although the exact color schema is a subject of possible further discussion, I used some, taken from both Powershell ISE and PowerGUI as an average. Here are groups instructions of the sample were split into.
1) the comments (green) group includes one-string comment beginning with the # sign and a multi-string comment applicable for advanced functions and consisting of all between <# and #> character sequences (sequences are included too).
2) commandlets and commands (some blue-gray color that has been used in the original WordPress’s coloration), and their aliases like Out-Null, Get-ChildItem, dir. There is a fixed list of them. Custom aliases and commandlets are not supposed to be colored due to the fact that WordPress doesn’t run any PS code and it’s completely unaware of new constructs.
3) data types and attributes (light-blue or green-blue) group constitutes of all the code in square parentheses but inner round parentheses.
4) the string data (brown) group is comprised of one-string declarations limited with single quotes or double quotes and a multi-string construction beginning with @’ and finishing at ‘@.
5) variable names (magenta) includes all unquoted string beginning with the $ sign and containing letters, numbers, underlines, question mark and colon. The dot is an end as well as the space.
6) specific words used within function declarations (bright blue). This groups the word function, and the function-related words param, begin, process, end inside curly brackets following the word function.
This color also can be used for statements like foreach, for, switch, if and so on.
7) function names (light lilac) of two types of occurrence: within the function declaration (that is, following the word function) and anywhere in the code. Function names usually contain letters, numbers and colons.
I hope that there is no need to repeat how lucky would be all WordPress Powershell bloggers if the WordPress developing team does the requested.
WordPress PowerShell Code Coloring Test
I have already written about how it’s possibly to post Powershell code here. As a year turned, why don’t check the state of affairs again?
My example is very simple and doesn’t cover all aspects of code. On the other hand, great sheets of code are not what is easily comparable with eyes.
1. This way my example is eyed in ISE:
Bugs are rare, however, it’s necessary to list them:
1.1 String data used without quotes is colored as a function (line 10)
1.2 Methods are not colored. It’s a typical trick, however, since nobody may know what it will be after the run of code. After having run the code, it’s considered here that no reason to re-color already colored code. (lines 10 and 42)
1.3 Property ‘Value’ is not colored (line 42).
Anyway, the coloring left the reader in a mood that all is healthy here.
2. Using Copy as HTML in PowerGUI 2.4 and Chrome 11, after adding manually line breaks (why doesn’t it type
s?), spaces and deleting trailing spaces after backticks (not in this sample), the following is workable:
cls #region WordPress posting code test #this is a test of Powershell code coloring [string]$stringVar1="string 1"; [string]$private:stringVar2='string 2'; [string]$script:stringVar3= @' string data '@ [scriptblock]$global:sb= {{Write-Hostscriptblock}.Invoke();}; function write1{Write-Host $stringVar1;} function private:write2 {param([string]$str2='')Write-Host $str2;} function script:write3 #this is a function { Write-Host$script:stringVar3; } function global:Print-SB { <# .SYNOPSIS This is a code coloring test. .DESCRIPTION This test function represents an advanced Powershell function syntax. .PARAMETER Param Demonstrates how a scriptblock can be passed as a reference. .EXAMPLE PS C:\> Print-SB ([ref]$sb) #> [CmdletBinding()] param( [Parameter(Position=0, Mandatory=$true)] [ref]$Param ) Begin{} Process{$Param.Value.Invoke()} End{} } write1 private:write2 $private:stringVar2; script:write3 Print-SB ([ref]$global:sb) #endregion WordPress posting code test
2.1 In the second code snippet we have numerous problems with names of functions, both where they are declared and where they are called.
2.2 Write-Host inside the second function
2.3 Such stuff like attributes in an advanced function.
To conclude this section, use the Copy as HTML option is a choice if manual editing doesn’t fatigue you.
3. WordPress provides a set of tags. Several parameters might do the life of a codeblogger simpler, especially 'highlight'.cls #region WordPress posting code test #this is a test of Powershell code coloring [string]$stringVar1 = "string 1"; [string]$private:stringVar2 = 'string 2'; [string]$script:stringVar3 = @' string data '@ [scriptblock]$global:sb = {{Write-Host scriptblock}.Invoke();}; function write1{Write-Host $stringVar1;} function private:write2 {param([string]$str2 = '')Write-Host $str2;} function script:write3 #this is a function { Write-Host $script:stringVar3; } function global:Print-SB { <# .SYNOPSIS This is a code coloring test. .DESCRIPTION This test function represents an advanced Powershell function syntax. .PARAMETER Param Demonstrates how a scriptblock can be passed as a reference. .EXAMPLE PS C:\> Print-SB ([ref]$sb) #> [CmdletBinding()] param( [Parameter(Position=0, Mandatory=$true)] [ref]$Param ) Begin{} Process{$Param.Value.Invoke()} End{} } write1 private:write2 $private:stringVar2; script:write3 Print-SB ([ref]$global:sb) #endregion WordPress posting code testHowever, the overall state is not appropriate, from my point of view. Yes, I know that the 'Frustration-Free' trademark is not WordPress's (as it is not Quest's too), but there is a room for improvement:
3.1 Variable names (lines 5, 6, 46, 48)
3.2 Function declarations and names (lines 11-13, 15, 21, 45-48)
3.3 A blob string (lines 7-9)
3.4 A specific to advanced functions comment-description (lines 23-35)
3.5 Types (lines 4-6, 10, 14)
3.6 Unquoted string (line 10)
I'll report these problems to Happiness engineers, maybe they share a bit of their happiness? 😉
PowerShell-disabled Areas On The Globe
A couple of weeks ago, I set the world-wide visitors widget (I love geography and maps). My blog is not a very popular place, being updated only from time to time, but the analysis is interesting.
From an independent point of view, examples of Winforms applications running in PowerShell should be equally interesting to people across the globe. However, it’s not so, far beyond from being so.
Let’s look at the coverage:
The US and Europe are undoubtedly global leaders. Western counties are the very center of PowerShell power, great and useful. Asia contributes too. Antipodes visit, but relatively rarely. The visitors are widespread across the US, whereas European ones are concentrated due to comparatively small sizes of their countries.
The most deserted areas like North Africa, Middle Asia, Western Australia and Greenland as well as South-American and African jungles are not supposed to hit the blog. The question here is Russia, with exception for Saint-Petersburg (my visits I suppose) it looks like a desert. Especially oddly does it seem like a Sahara in its European part. What may be the cause of this desertification effect? As I heard, some people in Moscow are aware of powershell advantages. Perhaps, the imperial tradition not to learn language but imperial one prevents guests from reading the blog? There is no answer, and never will be until Russian non-visitors explain such an evasion. 🙂
An Infinitesimal Update To ObjectBrowser
Hi, today’s update is really small.
– added a progress bar during the collecting Current AppDomain and GAC. This should do the GAC loading slightly less painful.
– the ability to be run from command line powershell as well as from ISE is now restored. Please use the following instruction to import the module:
Import-Module Add-on.PSDevStudioLite.ObjectBrowser -Force
Other changes relate to internal code structure and not to be seen right now in the GUI. As usual, the download location is here: http://www.box.net/shared/ot56ct7ngl
Preventing Problems In Your PowerShell Code
Last month a wave of using the Set-StrictMode commandlet flooded the PowerShell Internet landscape.
In receiving occasionally a tweet from powershell.com about using it with the -Version Latest parameter, I re-wrote several my old modules, three plus lines each, to meet the requirement. Needless to say that it helped to fix some deep mistakes in code, causing to reduction of code execution. These modules collect information, so that their execution don’t stop, but the data collected are not complete.
The topmost problem was the use of CSharp-like variable checks:
if ($Variable -ne $null){
Owing to a habit of using such a style, I left intact these checks, only outermost try-catch statements were added:
try{$null = $Variable; if ($Variable -ne $null){ }}catch{}
where catch instruction empty or contains the error-handling function, just depending on a situation. Especialy, if what is meant to be $Variable is something like $Variable.Property.
Bringing the first story to an end, I need to say that my style of error-handling is formed mostly on recommendations given in John Robbins’s book about .NET debugging, the second edition if I recall it right. He insisted on testing return values and input parameters rather than on generating exceptions, so that I picked up this style somewhere in this millennium.
The example above is typical of such an approach: try statement is used as a protection level 1 from error thrown by Set-StrictMode, at the same time, the if statement defends the furthermost code from a useless value of a variable, forming level 2 of protection. In common, it works well, but weights heavy.
Not so much time went out since I finished tayloring mycode to support the Set-StrictMode cmdlet, here came a new issue I must investigate: http://www.windowsitpro.com/blogs/powershell-with-a-purpose/entryid/76307/is-there-an-option-explicit-in-powershell
Don warned on scopes. Personally, someday I had a problem like:
for($i = 0; $i -lt 10; $i++) { #some code for($i = 0; $i -lt 10; $i++) { #some code } }
In this example, the index variable omits several states as a result of being increment in the inner cycle:
for($i = 0; $i -lt 10; $i++) { Write-Host $i; for($i = 0; $i -lt 10; $i++) { Write-Host $i; } }
0
0
1
2
3
4
5
6
7
8
9
The following sample code does the same:
for($private:i = 0; $private:i -lt 10; $private:i++) { Write-Host $private:i; for($private:i = 0; $private:i -lt 10; $private:i++) { Write-Host $private:i; } }
To heal the situation, you need use as many unique names of variables as you can afford. I suppose, you might have tens of cycles in your code. The following example is that you need to cure the preceding one:
for($private:i = 0; $private:i -lt 10; $private:i++) { Write-Host $private:i; for($private:i2 = 0; $private:i2 -lt 10; $private:i2++) { Write-Host $private:i2; } }
There may be offered a dubious solution, that some people used in VBScript programming: to declare ALL the script variables at a begin of every script/module file.
The argument that there is a great memory consumption is not serious due to a usual great memory consumption of many PowerShell scripts callingmodules and gathering some data.
Following the previously mentioned, the protected code is something like:
[int]$private:i = 0; [int]$private:i2 = 0; # #amount of code # for($private:i = 0; $private:i -lt 10; $private:i++) { Write-Host $private:i; for($private:i2 = 0; $private:i2 -lt 10; $private:i2++) { Write-Host $private:i2; } }
Along with this ‘scope problem’, there’s another scope problem, namely ’embedded variable problem’. Notice, that variables $_, $Error and several other might contain various values at the execution time.
I saw the code where these variables worked differently on a module load and in time module functions are called. This was because of using Import-Module with the -Force parameter. Global value of $_ can be easily spoilt, so can be spoilt $script:_, but this is observed not so frequently.
The last example of today’s article demonstrates how we can spoil the $global:_ variable. It’s supposed that you have a couple of module *.psm1 files in paths stored in the $PSMOdulePath variable. If you does, let’s see how values of $global:_ and $script:_ are changed:
cls [int]$counter = 0; $env:PSModulePath.Split(";") | %{Get-ChildItem -Path $_ -Include *.psm1 -Recurse | %{Write-Host '1' $_; $counter++; if ($counter -eq 1) { $module = "${env:temp}\test.psm1" @' function Out-Items { param([string]$Comment) [string]$private:regPath = ` 'Registry::HKCU\Keyboard Layout'; Get-ChildItem $private:regPath | ` Select-Object -First 1 | ` %{Write-Host 'Registry' $Comment '$_ :' $_; Write-Host 'Registry' $Comment '$private:_ :' $private:_; Write-Host 'Registry' $Comment '$local:_ :' $local:_; Write-Host 'Registry' $Comment '$script:_ :' $script:_; Write-Host 'Registry' $Comment '$global:_ :' $global:_;}; } Out-Items 'on loading the module'; Export-ModuleMember -Function Out-Items '@ > $module Import-Module $module -Force; } Write-Host '2' $_; }} Out-Items "called from the console";
The salvation is in using bracketing with {}.GetNewclosure() method as shown below:
cls [int]$counter = 0; $env:PSModulePath.Split(";") | %{Get-ChildItem -Path $_ -Include *.psm1 -Recurse | %{Write-Host '1' $_; $counter++; if ($counter -eq 1) { $module = "${env:temp}\test.psm1" @' function Out-Items { param([string]$Comment) [string]$private:regPath = ` 'Registry::HKCU\Keyboard Layout'; Get-ChildItem $private:regPath | ` Select-Object -First 1 | ` %{Write-Host 'Registry' $Comment '$_ :' $_; Write-Host 'Registry' $Comment '$private:_ :' $private:_; Write-Host 'Registry' $Comment '$local:_ :' $local:_; Write-Host 'Registry' $Comment '$script:_ :' $script:_; Write-Host 'Registry' $Comment '$global:_ :' $global:_;}.GetNewclosure(); } Out-Items 'on loading the module'; Export-ModuleMember -Function Out-Items '@ > $module Import-Module $module -Force; } Write-Host '2' $_; }} Out-Items "called from the console";
Source Control, PoshCode or Cloud?
How do you individual scripters store your scripts at a time they are not finished?
For companies and groups of scripters, undoubtedly, source control systems available across the Internet is the best choice. In case you need to obtain a specific information like who changed particular pieces of the code or have date-time labels set automatically, nobody argues that these systems do it well. But, from the point of view of a script-writing individual, this way requires extra preparations, including source control client being set across the hosts one uses to run and tune a script, sometimes firewall settings should be taylored to allow access to.
When scripts are released, there is no hesitation that global storages like SourceForge, CodePlex or PoshCode are the reasonable choice to share your code. Beforehand their upload there, the question on where do I save a draft is not answered. Maybe, with an exception for portals providing both publishing facilities and source controls ones. With aforementioned restrictions.
Alternatively, geeks might use flash memory, since no one commutes or moves from place to place without a mobile, some media player or even storage embedded in almost anything similarly to represented here http://goo.gl/MmOWD .
Recently, I found one more possibility to get access to my drafts across the Internet. No, this is not my mailbox (though it’s also in use for these purposes). It’s not a box.net, a plug-in I use for this WordPress blog, too. It’s Amazon CloudDrive.
If an ad-blocking system in your browser hasn’t cut off the tail fo this post, I’m glad to drop a couple of words about this free filebox. They give us 5 gigabytes of place gratuitously, we are permitted to upload files as to pre-created folders as well to folders of our choice.
In the picture above, my new personal dropbox is shown. As can be seen, I created the folders structure /Projects/PS for my draft scripts. It will be filling as I change any of my scripts, at least as an additional protected storage in case of emergency like hard drive crash.
If one bought an mp3 album, the place it took are not substituted from yours 5GB. Moreover, you obtain twenty gigabytes on everyday buying only one mp3 album, details of the bargain explained here http://goo.gl/2F8YE .
Not surprisingly, that you now can use this storage for listening to files you bought at the Amazon’s cornershop, by using Cloudplayer. However, if you are an audiobooks consumer like me, not a musician, there is no solution solving the problem how to use the CloudPlayer for enjoying books.
Anyway, this is a perfect storage for quotidian use, even before ou have a plugin to put your files there and back to you directly from Powershell. Has anybody written a sample yet that can be rewritten as a module intended for handling data is this storage?






