Windows Vista Forums
Vista Forums Home Join Vista Forums Windows 7 Forum Vista Tutorials Tags
Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks.

Go Back   Vista Forums > Misc Newsgroups > PowerShell

Vista - Skeleton for file processing scripts

Reply
 
Old 01-05-2007   #1 (permalink)
Maximilian Hänel


 
 

Skeleton for file processing scripts

Hi,

I often need a script that operates on files. While it isn't that hard
to write such a script, writing it the right way can be a tedious task.
By "right way" I mean that the script should support a path and
literalPath parameter as well as pipline input. It should support
globbing and the ability to bind to an objects path property. So here's
what the skeleton currently looks like:

# Process-File.ps1
param(
[object]$path,
[string]$literalPath
)
begin
{
function ProcessFile([IO.FileInfo]$file)
{
# actual implementation goes here
$file
}
function ProcessInput($i)
{
if(! $i){return}

if($i -is [IO.FileInfo])
{
ProcessFile $i
}
elseif($i -is [IO.DirectoryInfo])
{
# skip directories
}
elseif($i.Path)
{
# Bind to the objects Path property
ProcessFile ([IO.FileInfo]$i.Path)
}
else
{
# support for globbing
foreach($pi in (resolve-path $i))
{
ProcessFile ([IO.FileInfo]$pi.Path)
}
}
}
}
process
{
ProcessInput $_
}
end
{
ProcessInput $path
if($literalPath)
{
ProcessInput ([IO.FileInfo]$literalPath)
}
}
#eof

By using this script as a starting point you only have to implement the
ProcessFile function. After doing so you can then use your script in the
following ways:

# Binds directly to the FileInfo object
PS> ls | .\Process-File.ps1

# Binds to the Path property of Process
PS> gps | .\Process-File.ps1

# Support for globbing
PS> .\Process-File.ps1 *.txt

# Support for an array of paths+globbing
PS> .\Process-File.ps1 *.txt,*.ps1

# Support for literalPath
PS> .\Process-File.ps1 -literalPath "[a-z].txt"

Did I miss something? Any comments?

cu

Max

My System SpecsSystem Spec
Old 01-09-2007   #2 (permalink)
Lee Holmes [MSFT]


 
 

Re: Skeleton for file processing scripts

That looks great. The script does a good job of handling some of the C#
cmdlet features that we want to eventually add to scripts in a more
first-class manner.

One thing that might cause confusion for readers of the script is the way
that it closely intertwines pipeline-oriented input with parameter-based
input. The script uses the pipeline control structures (begin, process, and
end,) but acts like a non-pipeline script for much of the rest.

An alternative approach you might consider is to explicitly foreach over
$input, as it might make your script easier to understand.

--
Lee Holmes [MSFT]
Windows PowerShell Development
Microsoft Corporation
This posting is provided "AS IS" with no warranties, and confers no rights.

"Maximilian Hänel" <ngSpam@smjh.de> wrote in message
news:uwdJ0cTMHHA.5104@TK2MSFTNGP06.phx.gbl...
> Hi,
>
> I often need a script that operates on files. While it isn't that hard to
> write such a script, writing it the right way can be a tedious task. By
> "right way" I mean that the script should support a path and literalPath
> parameter as well as pipline input. It should support globbing and the
> ability to bind to an objects path property. So here's what the skeleton
> currently looks like:
>
> # Process-File.ps1
> param(
> [object]$path,
> [string]$literalPath
> )
> begin
> {
> function ProcessFile([IO.FileInfo]$file)
> {
> # actual implementation goes here
> $file
> }
> function ProcessInput($i)
> {
> if(! $i){return}
>
> if($i -is [IO.FileInfo])
> {
> ProcessFile $i
> }
> elseif($i -is [IO.DirectoryInfo])
> {
> # skip directories
> }
> elseif($i.Path)
> {
> # Bind to the objects Path property
> ProcessFile ([IO.FileInfo]$i.Path)
> }
> else
> {
> # support for globbing
> foreach($pi in (resolve-path $i))
> {
> ProcessFile ([IO.FileInfo]$pi.Path)
> }
> }
> }
> }
> process
> {
> ProcessInput $_
> }
> end
> {
> ProcessInput $path
> if($literalPath)
> {
> ProcessInput ([IO.FileInfo]$literalPath)
> }
> }
> #eof
>
> By using this script as a starting point you only have to implement the
> ProcessFile function. After doing so you can then use your script in the
> following ways:
>
> # Binds directly to the FileInfo object
> PS> ls | .\Process-File.ps1
>
> # Binds to the Path property of Process
> PS> gps | .\Process-File.ps1
>
> # Support for globbing
> PS> .\Process-File.ps1 *.txt
>
> # Support for an array of paths+globbing
> PS> .\Process-File.ps1 *.txt,*.ps1
>
> # Support for literalPath
> PS> .\Process-File.ps1 -literalPath "[a-z].txt"
>
> Did I miss something? Any comments?
>
> cu
>
> Max



My System SpecsSystem Spec
Old 01-09-2007   #3 (permalink)
Maximilian Hänel


 
 

Re: Skeleton for file processing scripts

Hi Lee,

> That looks great.


Thanks for feedback!

> The script does a good job of handling some of the C#
> cmdlet features that we want to eventually add to scripts in a more
> first-class manner.


Nice! Do you have a PowerShell "roadmap"? I'm curious when we can expect
the next release ;-)

> One thing that might cause confusion for readers of the script is the way
> that it closely intertwines pipeline-oriented input with parameter-based
> input. The script uses the pipeline control structures (begin, process, and
> end,) but acts like a non-pipeline script for much of the rest.
>
> An alternative approach you might consider is to explicitly foreach over
> $input, as it might make your script easier to understand.


Hmm, sounds interesting. Let me see if I understood you right:

param(
[object]$path,
[string]$literalPath
)

function ProcessFile([IO.FileInfo]$file)
{
# TODO: implement ProcessFile
$file
}

function ProcessInput($i)
{
if($i -is [IO.FileInfo])
{
ProcessFile $i
}
elseif($i -is [IO.DirectoryInfo])
{
# always skip directories
}
elseif($i.Path)
{
# Bind to the objects Path property
ProcessFile ([IO.FileInfo]$i.Path)
}
else
{
# support for globbing
foreach($pi in (resolve-path $i))
{
ProcessFile ([IO.FileInfo]$pi.Path)
}
}
}

# process pipline input if present
if($input)
{
foreach($pi in $input){ProcessInput $pi}
}

# process path argument if present
if($path)
{
ProcessInput $path
}

# process $literalPath argument if present
if($literalPath)
{
ProcessInput ([IO.FileInfo]$literalPath)
}
#eof

cu

Max
My System SpecsSystem Spec
Old 01-10-2007   #4 (permalink)
Lee Holmes [MSFT]


 
 

Re: Skeleton for file processing scripts

That's exactly what I meant

As for the roadmap, our next big goal is to provide you guys with remoting
support. Speculation past that would be a little premature right now.

--
Lee Holmes [MSFT]
Windows PowerShell Development
Microsoft Corporation
This posting is provided "AS IS" with no warranties, and confers no rights.


"Maximilian Hänel" <ngSpam@smjh.de> wrote in message
news:uvnPCpDNHHA.536@TK2MSFTNGP02.phx.gbl...
> Hi Lee,
>
>> That looks great.

>
> Thanks for feedback!
>
>> The script does a good job of handling some of the C# cmdlet features
>> that we want to eventually add to scripts in a more first-class manner.

>
> Nice! Do you have a PowerShell "roadmap"? I'm curious when we can expect
> the next release ;-)
>
>> One thing that might cause confusion for readers of the script is the way
>> that it closely intertwines pipeline-oriented input with parameter-based
>> input. The script uses the pipeline control structures (begin, process,
>> and end,) but acts like a non-pipeline script for much of the rest.
>>
>> An alternative approach you might consider is to explicitly foreach over
>> $input, as it might make your script easier to understand.

>
> Hmm, sounds interesting. Let me see if I understood you right:
>
> param(
> [object]$path,
> [string]$literalPath
> )
>
> function ProcessFile([IO.FileInfo]$file)
> {
> # TODO: implement ProcessFile
> $file
> }
>
> function ProcessInput($i)
> {
> if($i -is [IO.FileInfo])
> {
> ProcessFile $i
> }
> elseif($i -is [IO.DirectoryInfo])
> {
> # always skip directories
> }
> elseif($i.Path)
> {
> # Bind to the objects Path property
> ProcessFile ([IO.FileInfo]$i.Path)
> }
> else
> {
> # support for globbing
> foreach($pi in (resolve-path $i))
> {
> ProcessFile ([IO.FileInfo]$pi.Path)
> }
> }
> }
>
> # process pipline input if present
> if($input)
> {
> foreach($pi in $input){ProcessInput $pi}
> }
>
> # process path argument if present
> if($path)
> {
> ProcessInput $path
> }
>
> # process $literalPath argument if present
> if($literalPath)
> {
> ProcessInput ([IO.FileInfo]$literalPath)
> }
> #eof
>
> cu
>
> Max



My System SpecsSystem Spec
Old 01-10-2007   #5 (permalink)
Maximilian Hänel


 
 

Re: Skeleton for file processing scripts

Hi Lee,

> That's exactly what I meant


:-)

> As for the roadmap, our next big goal is to provide you guys with remoting
> support.


Cool!

> Speculation past that would be a little premature right now.


That's too bad... ;-)

Thanks again,

Max
My System SpecsSystem Spec
Reply

Thread Tools


Similar Threads
Thread Forum
Running file iteration and other scripts under Vista security. How VB Script
Log In Out File Processing PowerShell
XML processing my web.config file in PowerShell PowerShell
Clear-Content Cmdlet and Processing Lines in Text File PowerShell
Script for automatically generating a .NET object-centered cmdlet skeleton PowerShell


Vista Forums is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
© Designer Media Ltd

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46