Blogroll

Search

Windows on ARM? Literally

May 1st, 2012 by Karl

For some reason my when thinking of Windows on ARM I started thinking of a literal human arm, and then thought of those little Nazi armband things from World War 2 then remembered various “fanart” of Bill Gates as Hitler so I did a good search. And sure enough Windows on ARM is not a new thing at all.

image

Posted in Powershell | No Comments »

Portable PowerShell for V3 Beta

April 25th, 2012 by Karl

We have released Portable PowerShell for V3 Beta. We have only gotten the 32bit version working so there is no 64 Bit, and also no ISE. We won’t be looking further into the issues we had with both until there is a next version of V3 whether its another CTP\Beta\Release Candidate or RTM. Also not all features may work. For instance I know that workflow doesn’t work. Many things do but we haven’t done a full feature comparison.

an important thing is if there are issues, don’t presume it’s a PowerShell V3 Bug, as it could be related to Portable PowerShell. Please do not submit bugs to Microsoft until you’ve validated them on real PowerShell.

You can go to www.portablepowershell.com and download it from there and also download the original Portable PowerShell that covers V1 and V2 both 32 and 64 bit, and also ISE.

or you can directly Download Portable PowerShell

image

Posted in Portable PowerShell, Powershell, PSV2, PSV3 | No Comments »

PS Gotcha: Scheduled Jobs and Battery

April 20th, 2012 by Karl

The other day I was working with a ne wPSV3 feature called Scheduled Jobs which is really cool as it allows you run some stuff as a Scheduled job, which uses the Scheduled Task engine to run it. You can set triggers like on start up, but unfortunately, and this is something I am frustrated about, not “immediately”. However you can trigger it to say run in 5 seconds which is long enough to ensure even a slow computer is going to get to it before the time expires and it would never .

So often I’ll do a demo like

Register-ScheduledJob -name quicktest -ScriptBlock { 1; sleep 5; 2} -Trigger (New-JobTrigger -Once -At (get-date).AddSeconds(4))
sleep 6
get-job quicktest | wait-job | Receive-Job

 

What this does is register a scheduled Job, which triggers in a few seconds, sleep to make sure it gets triggered, then uses get-job , which gets the job INSTANCE of the scheduled job, and does the normal stuff to wait and receive the data.

This works all good and dandy. Other than when it doesn’t, which according to the laws of DEMO, happens in a demo. So I ran something like this, and the job never seemed to be triggered. I tried again and again and I just couldn’t get it to work. and from the PowerShell side of things there just was no indication of error. it is as if I had never tried to run it.

image

 

So I started poking around in Task Scheduler. PowerShell stores the Scheduled tasks at \Microsoft\Windows\PowerShell\ScheduledJobs

image

 

Aha found the culprit. I was taking my laptop somewhere else to do the demo and had plenty of battery, However by default (not a bad thing) scheduled Tasks won’t launch when on battery.

It is a shaming pity that PSV3 doesn’t capture the error and create and failed job instance with the error. that would be definitely useful, and consistent with the PowerShell Job experience in general. At least we should have a Cmdlet that can show us warnings and errors for our scheduled jobs.

There are many reasons why a scheduled task can’t launch , from permissions, to this battery thing, to concurrency issues (i.e by default the policy only allows once instance of a scheduled task to run at once)

In my sample I could have just updated the policy to allow it to run on battery (-ScheduledJobOption (New-ScheduledJobOption -StartIfOnBattery), but still the point is it failed, and there was no indication of why. So be aware of these situations and work around them.

Register-ScheduledJob -name quicktest -ScriptBlock { 1; sleep 5; 2} `
-Trigger (New-JobTrigger -Once -At (get-date).AddSeconds(4)) `
-ScheduledJobOption (New-ScheduledJobOption -StartIfOnBattery)
sleep 6
get-job quicktest | wait-job | Receive-Job

Posted in Gotchas Etc, Powershell, PSV3 | No Comments »

Calling PowerShell V3 from Orchestrator 2012

April 16th, 2012 by Karl

The problem with calling PSV3 from Orchestrator 2012 is that PSV3 runs on the CLR V4, while Orchestrator runbooks and the Invoke.Net Activity run in a CLR V2 Process, so it automatically Binds PowerShell Version 2. So even if you have installed PowerShell Version 3 (currently in Beta) on your runbook server if you run a dotnetscript like below

image

When you run it, even though you are in PSV3 its running on the V2 engine so you see this result

image

So how can we call V3 easily? Well there are hard ways, with using some loopback remoting to V3, or building your own integration pack that does some interprocess communication to a special PowerShell host sending data back and forth, maybe via a COM server, but there is an easier way

In PowerShell you can call PowerShell from powershell you can do something like

$a = powershell { 1..10 }

powershell then loads a child process, runs the scriptblock (the 1 to 10) it then gets serialized , returned to the host Process and deserialized.

The good thing here is when V3 is installed the Child Process will be PowerShell V3. So lets put this to the test.

image

and sure enough.

image

So now you can from your V2, call V3 and get results, How can you actually pass info from Orchestrator to V3. Well its actually easier than in plain PowerShell since orchestrator 2012 simply just edits the text of your script before you run it.

image

However maybe you want to actually pass it in, and pass in a variety of info and do it a more “PowerShelly” way. in that case you can Pipe in an object (or a collection of objects) to your call to PowerShell, and it will be available in that child PowerShell process as the variable $input

So in the next example. I create a PowerShell custom object containing more than one piece of info. a string and something from the databus. I pipe it into the PowerShell { } and then do some processing , returning a customobject with 3 properties.. one the powershell version, and the other just modified versions of the input (i.e uppercase). Then I bring that object back and break it out into individual variables for the “invoke dotnet script” to publish on the databus.

 

Below is my published data.

image

and here is the code.

image

#prepare data to pass
$databusvar = "\`d.T.~Ed/{2B4BE08D-BD2D-4ACD-856C-83764177F88B}.databusvar\`d.T.~Ed/"
$someotherthing = "someother"
$inobj = new-object pscustomobject -property @{
    databusvar = $databusvar
    other=$someotherthing
 }
#call powershell V3
$theresults = $inobj | PowerShell {
    #use the special $input variable, just get the first item in case multiple
    #objects were piped in. (which weren't in this case)
    $inobject = $input | select -first 1
    #return results
    new-object pscustomobject -property @{
        version = " from Version $($PSVersionTable.psversion.tostring())"
        databusuppercase = $inobject.databusvar.toupper()
        hellorunbook = "hello $($inobject.other)"
       }
 }
#take the results from property and put them in variables for
#the invoke.net script activity to pick up and publish on the databus
$theversion = $theresults.version
$other = $theresults.hellorunbook
$databusvar = $theresults.databusuppercase

.

and now the proof of the pudding.

image

and there you have it full round trip, multiple items of data in (including from the databus), calling PowerShell Version 3, and returning multiple items and publishing them to the databus.

Posted in Orchestrator 2012, Powershell | No Comments »

Jobs Started from a workflow continue to run even with the workflow finishes or suspends.

March 23rd, 2012 by Karl

I plan on writing many articles about PowerShell workflow based on a lot of deep work I’ve done quite lately, but here is a random interesting fact.
Typically in PowerShell if you start a job say from inside another  PowerShell { … } process when that PowerShell process dies, all the processes it created are also terminated. However in Workflow by the nature of how the engine works with Processes and Processes in the workflow Endpoint this isn’t the case. You can start a job, whether using the workflow Start-Job activity, or using the Start-Job Cmdlet from inside an inlinescript and if the workflow ends, the job still works.. Even if the workflow SUSPENDS this is the case.

This isn’t bad, its just something to be aware of.

here is the proof first with the start-job activity

workflow x {
 start-job -scriptblock { 1..10 | % {sleep -second 1; $_ | out-file c:\temp\outtest.txt -append }  }
 Start-Sleep -Seconds 1
}
x

and secondly as an inline script

workflow x {
 inlinescript { start-job -scriptblock { 1..10 | % {sleep -second 1; $_ | out-file c:\temp\outtest.txt -append }  } }
 Start-Sleep -Seconds 1
}
x

Posted in Powershell, PSV3, workflow | No Comments »

USING for PowerShell?

March 5th, 2012 by Karl

One thing that many C# folks complain about PowerShell , is that while it lives in the DotNet ecosystem and works with DotNet objects it doesn’t have a Using statement that is in C# that works into a very foundational concept in the DotNet Type system and that is Idisposable.

However PowerShell’s flexibility afforded to it by scriptblocks comes to the rescue allowing you something that looks and feels rather similar. Here is a function that takes in a variable that is Idisposable, and a scriptblock, and runs the scriptblock, with the variable being accessible with $_

function use-var([idisposable]$instance, [scriptblock]$scriptblock)
{

  try
  {
    $instance | %  $scriptblock
  }
  finally
  {

    $instance.dispose()
  }
}

And an example

use-var (new-object system.io.memorystream 40) {
  $_.writebyte(40);
  $_.writebyte(20);
  $_.toarray();
  $_.close();
}

 

I should take the time and build it out more robustly as an advanced function etc. but it’s a starting point.

Posted in Powershell | No Comments »

All your IP V6 Addresses are belong to US

February 2nd, 2012 by Karl

I often have to write code that is automating against a lot of different machines, but when developing that code I often just want to loopback to the local machine. However most of my code wants to ensure the machine name is unique, so I have limitations as in I can use the actual machine name, localhost,  or 127.0.0.1 . Previously I had occasionally put multiple entries in the HOST file that resolved to 127.0.0.1 and it would work, however with certain security techs like CredSSP remoting fails over, plus it’s a horrid way to do unit tests having to change the state of your machine you are running them on to make the test work.

often 3 is not enough when I’m trying to do something like process a throttled queue of work with 40 items in it, running 4 concurrently etc and that caused pain. With IP v6 I discovered I could do ::1 which is nice and pithy but after a while I discovered the variations of acceptible IPv6 adresses for ::1 are HUGE and this gave me all the ammunition I needed to produce sample loopback “machine names” for my unit tests. Here is an example of some acceptable variations:

 

Test-Connection "localhost" -Count 1
Test-Connection "127.0.0.1" -Count 1
Test-Connection "::1" -Count 1
Test-Connection "0:0:0:0:0:0:0:1" -Count 1
Test-Connection "0::0:0:0:0:0:1" -Count 1
Test-Connection "0:0::0:0:0:0:1" -Count 1
Test-Connection "0:0:0::0:0:0:1" -Count 1
Test-Connection "0:0:0:0::0:0:1" -Count 1
Test-Connection "0:0:0:0:0::0:1" -Count 1
Test-Connection "0:0:0:0:0:0::1" -Count 1

Test-Connection "00:00:00:00:00:00:00:01" -Count 1
Test-Connection "00:00:00:00:00:00:00:1" -Count 1
Test-Connection "00::00:0:00:0:00:1" -Count 1
Test-Connection "000:000:000:000:000:000:000:01" -Count 1
Test-Connection "000:000:000:000:000:000:000:0001" -Count 1
Test-Connection "::0001" -Count 1
Test-Connection "::001" -Count 1
Test-Connection "0000:0::001" -Count 1

 

Challenge to you. Make a function that can return X number of acceptible variations. There seem to be some rules, like :: can skip one of the items, but can only be used once, and each item can have up to 3 leading digits and there can be combinations. What is the total number of acceptable variations?

Posted in Powershell | No Comments »

Expressions in PowerShell with “statement keywords”

December 17th, 2011 by Karl

Most developers who have followed the traditional imperative procedural through object orientated programming language legacy and particularly the family of C languages may be unaware of certain PowerShell features, while those who have exposure to a number of more dynamic languages may find this second nature but here are two facts about PowerShell

  • all statements can return data and be assigned.
  • because of the pipeline a statement of a group of statements can return more than one item.

in C languages many are aware of the ternary operator and use it as a way to have “pure” expressions so you may see something like

int a = (somevalue) ? 2 : 3

however if its more complicated , where rather than just plain values it may have to call a statement they have to go back to the stone age and do something like

int a;
if (somevalue) a = getsomenumber(); else a = 3

and lets say you were wanting to return an array generated in a for loop you had to define your array or collection outside, then populate it internally, you couldn’t just generate the values and return them. Well in PowerShell you can. Most of you are used to doing this in the case of calling Cmdlets and also maybe processing in the pipeline with Foreach, or with subexpressions using $( ) but you can do this with all language statements.. here is a few examples

$x  = if ($true) { "yo" } else { "no" }

Here you can see three things.

  • we are assigning the result of the if statement as if it were a ternary operator
  • we are running code , this could be calling any code
  • we are implicitly return data (which goes into the pipeline, and then gets collected into the variable. In this case we are only returning one item but you can do more.
$result = for($a = 0; $a -lt 100;$a++) { $a + $a ; "hello $a" }

in this next case we are using a for statement, and each iteration output 2 objects. so $result will contain an array with a size of 200 items with an integer and string interleaved each second item.

image

With this technique you can simplify and do lots of cool and interesting things, and while it may not seem as readable to somebody with a C language legacy, it’s common in a number of dynamic languages. the switch statement, which in powershell is super powered anyway can be used in this context very well.

Posted in Powershell | No Comments »

Calling PowerShell 64bit from 32bit and visa versa

November 4th, 2011 by Karl

So why would somebody want to call 64bit PowerShell for a 32bit PowerShell process or visa versa? Well there are numerous reasons but sometimes you happen to be in a host that is on kind of process (maybe triggered by SCCM, or inside a Opalis/Orchestrator runbook, or a custom application, but there are either dotnet Classes, Snapins or Modules, or even COM Objects that are soley of the opposite bitness. Sometimes your code actually has to do something that requires for instance a 64bit SnapIn, but also uses a COM object that is 32bit only.

So first how can we detect whether we are in a 64bit or 32bit process so our code can make a decision what to do? Well a 64bit Pointer is 64bits and as a byte is 8bits then 64/8 takes up 8 Bytes of space, while a 32bit weighs in at 4 Bytes. In Dotnet a convenient way to find this out is to see what the size of an IntPtr is with [IntPtr]::Size

image

So if you are in a 64bit Process , and want to call some 32Bit code, either waiting for it to finish or in the background, if you have PowerShell V2 or up. its easy. you can use Start-Job which normally will start a process in the same bitness as you but there is a parameter called –Runas32 . This is great and convenient and easy to use, and there are also other features like being able to use specific credentials easily.

Because jobs run in the background, if you want to wait and get the results you can pipe it to Wait-Job and then to Receive-Job. Here is an example

start-job { [intptr]::Size } -RunAs32 | wait-job | Receive-Job

and to prove that its doing what it should lets run it from a 64bit shell.

image

So with all this goodness we’d hope that when in 32 bit PowerShell there would be a –RunAs64 switch, but alas our hopes are fruitless in this case.

So what does a 32 Bit backwater admin do to escape this pain? Aha. we can call the PowerShell EXE directly!! I know where it lives

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

However we find that our new PowerShell is actually still 32 Bit? What is going on? We’ll system32 inside a 32bit process is redirected to the 32bit System32 which following Microsoft’s great legacy of confusing names is called SysWow64. So on a 64bit box, the real 64 bit system directory is System32 while the 32bit is SysWow64 !!! Man all these layers of confusion. If only we could just go native.

well that’s the key. There is an “invisible” folder name when inside a 32bit that lets you actually go inside the 64bit System32 directory and its called Sysnative. so lets try it out

image

and if you do the same this refering to Syswow64 from inside a 64 bit process you can load 32 bit powershell

image

So how can we best use this. We’ll I ussually have a quite complicated function that will test what bitness I am and do the sysnative \syswo64 trick only if needed However the simplest thing is just to make a couple of aliases.

set-alias ps64 "$env:windir\sysnative\WindowsPowerShell\v1.0\powershell.exe"
set-alias ps32 "$env:windir\syswow64\WindowsPowerShell\v1.0\powershell.exe"

and here is an example using it, piping in data and also verifying the bitness difference

image

Just be aware that syswow64 won’t resolve when inside 32bit and sysnative won’t resolve when inside a 64bit process, so its best to make some nice robust wrapper functions.

Posted in Powershell | No Comments »

Functions with process blocks versus functions without process blocks.

October 4th, 2011 by Karl

What’s the difference between a function with a process block versus one without?

When you have a process block

  • you can have a begin and end as well (optionally)
  • the process block is called for each item in the pipeline and you can reference it via $_ (if a simple function, otherwise through a parameter with ValueFromPipeline from an advanced function)
  • you can’t access $input (you have $_ in process instead)
function fullfunction
{
 begin
  {
   write-warning "in begin"
   "from beginning"
  }
 process
  {
   write-warning "in process $_"
   "from process"
  }
 end
  {
   write-warning "in end"
   "from end"
  }
}
1..3 | fullfunction

image

When you don’t have a process block

  • Its effectively an END block
  • you break streaming of the pipeline. So if you have 1..10 | streaming-something | mydumbfunction | streaming-somethingelse  the dumbfunction stops streaming and doesn’t output anything to the downstream until the end.
  • you can reference the COMPLETE pipeline input with $input
  • you can a end block and put the code in that (same effect)
function simplefunction
{
 end {
 $input | % { "processing each item in $input with foreach $_ " }
 }
}
1..5 | simplefunction

processing each item in 1 with foreach 1
processing each item in 2 with foreach 2
processing each item in 3 with foreach 3
processing each item in 4 with foreach 4
processing each item in 5 with foreach 5 

Posted in Powershell | No Comments »

« Previous Entries