Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How do I get absolute path of a file?

57 views
Skip to first unread message

Megaton

unread,
Nov 17, 2009, 7:53:02 PM11/17/09
to
Hi

I would like to copy a collection of .doc files to C:\ one by one and print
out on screen.

What I am doing is first getting a collection of doc files:
$docs = get-childitem -recurse d: | where-object {$_.Name -like "*.doc"}

then I use a foreach loop to go through these .doc files

foreach ($doc in $docss)
{
copy-item $doc c:\
write-host "Copied file ""$doc"" to directory: C:\"
}

but the problem is that the copy-item statement looks for files under the
current working directory so I get lots errors. How do I get the path for
each $doc?
I am new to PowerShell. Thank you for your help!

Al Fansome

unread,
Nov 17, 2009, 9:31:13 PM11/17/09
to
Using the foreach loop:

foreach ($doc in $docs)
{
copy-item $doc -destination c:\
}

Slightly simpler:

$docs | copy-item -destination c:\

Al Fansome

unread,
Nov 17, 2009, 9:34:27 PM11/17/09
to
Oops, actually

copy-item $doc.fullname c:\

works. Sorry.

Megaton

unread,
Nov 17, 2009, 10:33:03 PM11/17/09
to
Worked like a charm. Thank you.

Larry__Weiss

unread,
Nov 17, 2009, 11:02:26 PM11/17/09
to
I'm wondering why you have to refer to a file's fullname property explicitly.

I thought that the object itself would have been defined well enough to resolve
it to a specific file resident at a specific location.

Isn't that the point of collecting the objects and not just the names?

- Larry

Al Fansome

unread,
Nov 17, 2009, 11:22:47 PM11/17/09
to
That's what I would have thought also. The only thing I can think of is
that copy-item is designed to work with strings when dealing with
positional arguments.

When piped, the file objects seemed to work:

$docs | copy-item -destination c:\

Larry__Weiss

unread,
Nov 18, 2009, 1:12:28 AM11/18/09
to
Except for a typo where you have $docss I don't see why that would not work.

I've recoded as

copy-item $doc c:\ -whatif

to see exactly how the paths are defined for the copies and I see what you are
saying. It seems like a bug to me.

Even recoding as

$docs | % { copy-item $_ c:\ -whatif }

does not help. I don't see what default property would cause it to lose a node
in the path during the copy from the items in subfolders.

- Larry

Martin Zugec

unread,
Nov 18, 2009, 3:58:13 PM11/18/09
to
Because default property to return is Name, not FullName...

You will get fullname by calling other .NET functions thought (retrieval of
files or subfolders returns array of strings)

Martin

"Larry__Weiss" <l...@airmail.net> wrote in message
news:OCC6zPAa...@TK2MSFTNGP05.phx.gbl...

Larry__Weiss

unread,
Nov 18, 2009, 4:49:19 PM11/18/09
to
I still feel there is something amiss about having to even refer to a name type
property when PowerShell and .NET are supposedly object-oriented by nature.

I'd think that we almost trip into the "parse and pray" swamp when we have to
worry about specific properties of the object instead of just naturally letting
the system refer to the whole object itself.

Why can't an unqualified $doc refer to the file system object that represents
that one particular file that resides at the Fullname locality?

- Larry

Martin Zugec wrote:
> Because default property to return is Name, not FullName...
> You will get fullname by calling other .NET functions thought (retrieval
> of files or subfolders returns array of strings)
>

> "Larry__Weiss" <l...@airmail.net> wrote in message
> news:OCC6zPAa...@TK2MSFTNGP05.phx.gbl...
>> I'm wondering why you have to refer to a file's fullname property
>> explicitly.
>> I thought that the object itself would have been defined well enough
>> to resolve it to a specific file resident at a specific location.
>> Isn't that the point of collecting the objects and not just the names?
>>
>>

Shay Levy [MVP]

unread,
Nov 22, 2009, 11:57:28 AM11/22/09
to
When you pipe files from Get-ChildItem to Copy-Item the pipeline use the
LiteralPath ParameterSet on both cmdlets. The LiteralPath ParameterSet contains
a parameter named 'LiteralPath' which has an alias names PSPath (added by
the filesystem providder). The files are binded by this property (ValueFromPipelineByPropertyName)
so there's no need to specify FullName.

When you use foreach-object or foreach statment you need to specify fullname
because these commands doesn't bind the FullName property.


Hope This helps


---
Shay Levy
Windows PowerShell MVP
http://blogs.microsoft.co.il/blogs/ScriptFanatic
PowerShell Toolbar: http://tinyurl.com/PSToolbar

L> I still feel there is something amiss about having to even refer to a
L> name type property when PowerShell and .NET are supposedly
L> object-oriented by nature.
L>
L> I'd think that we almost trip into the "parse and pray" swamp when we
L> have to worry about specific properties of the object instead of just
L> naturally letting the system refer to the whole object itself.
L>
L> Why can't an unqualified $doc refer to the file system object that
L> represents that one particular file that resides at the Fullname
L> locality?
L>
L> - Larry
L>
L> Martin Zugec wrote:
L>

Larry__Weiss

unread,
Nov 22, 2009, 5:12:31 PM11/22/09
to
Then I guess my concern is better stated that I'd prefer the foreach-object or
foreach statement to bind the FullName property.

What design concerns prevented the binding?

- Larry

Shay Levy [MVP]

unread,
Nov 23, 2009, 4:15:42 AM11/23/09
to
Why use foreach-object when you pipe directly to copy-item?


> What design concerns prevented the binding?


foreach-object cannot bind by property name because it has no equivalent
parameters as Get-ChildItem and the foreach statement (loop) is not pipelinable.

---
Shay Levy
Windows PowerShell MVP
http://blogs.microsoft.co.il/blogs/ScriptFanatic
PowerShell Toolbar: http://tinyurl.com/PSToolbar

L> Then I guess my concern is better stated that I'd prefer the
L> foreach-object or foreach statement to bind the FullName property.
L>
L> What design concerns prevented the binding?


L>
L> - Larry
L>

L> Shay Levy [MVP] wrote:
L>

Larry__Weiss

unread,
Nov 23, 2009, 10:43:48 AM11/23/09
to

Here is the original poster's code example

$docs = get-childitem -recurse d: | where-object {$_.Name -like
"*.doc"}

foreach ($doc in $docs)


{
copy-item $doc c:\
write-host "Copied file ""$doc"" to directory: C:\"
}

Perhaps it is the need for the multiple statement block (copy-item then
write-host) that makes this more complicated than a simple pipeline.

- Larry

Larry__Weiss

unread,
Nov 23, 2009, 1:11:20 PM11/23/09
to

I have been able to eliminate the foreach loop, yet the situation persists.
If I code it as

$docs = get-childitem -recurse d: | where-object {$_.Name -like "*.doc"}
$docs | %{process{copy-item $_ -destination c:\ -whatif}}
it doesn't find the files in the subfolders
Coding as

$docs = get-childitem -recurse d: | where-object {$_.Name -like "*.doc"}
$docs | %{process{copy-item $_.fullname -destination c:\ -whatif}}
does find all files.


Here is a simpler example
get-childitem -recurse | %{process{copy-item $_ -destination c:\ -whatif}}

versus

get-childitem -recurse | %{process{copy-item $_.fullname -destination c:\ -whatif}}

This still requires the $_.fullname explicitness to process all files in the
hierarchy.

- Larry

Larry__Weiss

unread,
Nov 23, 2009, 1:36:48 PM11/23/09
to
In my tests, the code pattern that gets the .doc files only, in all subfolders,
and allows processing without the explicit fullpath property turns out to be

get-childitem -include *.doc -recurse | %{process{get-item $_}}


With variation

get-childitem -include *.doc -recurse | %{process{copy-item $_ -destination c:\ }}

and

get-childitem -include *.doc -recurse | %{process{copy-item $_ -destination c:\
; write-host "Copied file ""$_"" to directory: C:\"}}

and also can be coded to use the foreach loop (with no need for the fullname
property to be called out)


$docs = get-childitem -include *.doc -recurse


foreach ($doc in $docs)
{
copy-item $doc c:\
write-host "Copied file ""$doc"" to directory: C:\"
}


- Larry

Larry__Weiss

unread,
Nov 23, 2009, 1:39:08 PM11/23/09
to
Try this variation:

$docs = get-childitem -include *.doc -recurse d:
foreach ($doc in $docs)


{
copy-item $doc c:\
write-host "Copied file ""$doc"" to directory: C:\"
}

- Larry

Shay Levy [MVP]

unread,
Nov 23, 2009, 4:51:55 PM11/23/09
to
Makes sense. If you need to include mutiple statments then foreach is the
way to go.


---
Shay Levy
Windows PowerShell MVP
http://blogs.microsoft.co.il/blogs/ScriptFanatic
PowerShell Toolbar: http://tinyurl.com/PSToolbar

L> Here is the original poster's code example
L>
L> $docs = get-childitem -recurse d: | where-object {$_.Name -like
L> "*.doc"}
L> foreach ($doc in $docs)
L> {
L> copy-item $doc c:\
L> write-host "Copied file ""$doc"" to directory: C:\"
L> }
L> Perhaps it is the need for the multiple statement block (copy-item
L> then write-host) that makes this more complicated than a simple
L> pipeline.

Larry__Weiss

unread,
Nov 23, 2009, 5:53:05 PM11/23/09
to
And did you notice from my subsequent posts that you can code it with foreach
and not have to use the -fullname parameter?


$docs = get-childitem -include *.doc -recurse d:
foreach ($doc in $docs)
{

copy-item $doc c:\
write-host "Copied file ""$doc"" to directory: C:\"
}

# -- instead of -- #


$docs = get-childitem -recurse d: | where-object {$_.Name -like "*.doc"}

foreach ($doc in $docs)


{
copy-item $doc c:\
write-host "Copied file ""$doc"" to directory: C:\"
}


It is not the where-object that makes the difference as this variation works OK

$docs = get-childitem -include *.doc -recurse d: | where-object {$_.Name -like
"*.doc"}
foreach ($doc in $docs)


{
copy-item $doc c:\
write-host "Copied file ""$doc"" to directory: C:\"
}


It is something that using the -include parameter to get-children does that
allows the default property to reference the item via its fullname.

I'm far from understanding why.

- Larry

Martin Zugec

unread,
Nov 25, 2009, 3:09:57 PM11/25/09
to
+1 - thinking about it, I use FullName much more often than simply Name

Martin

"Larry__Weiss" <l...@airmail.net> wrote in message

news:u$s6kD8aK...@TK2MSFTNGP06.phx.gbl...

ryan

unread,
Feb 14, 2010, 4:52:41 AM2/14/10
to
ls d:\ -r -i *.doc | %{ write-host "copying $_.fullname to C:\"; cp
-literalpath $_.fullname c:\ }

Shay Levy [MVP]

unread,
Feb 14, 2010, 9:22:52 AM2/14/10
to

Hi Ryan,


When you need to expand object.property inside strings, put object.property
in a subexpression ( e.g $(...))


write-host "copying $($_.fullname) to C:\"


---
Shay Levy
Windows PowerShell MVP
http://blogs.microsoft.co.il/blogs/ScriptFanatic
PowerShell Toolbar: http://tinyurl.com/PSToolbar

R> ls d:\ -r -i *.doc | %{ write-host "copying $_.fullname to C:\"; cp
R> -literalpath $_.fullname c:\ }
R>
R> On 11/18/2009 8:53 AM, Megaton wrote:
R>

ryan

unread,
Feb 14, 2010, 9:41:31 AM2/14/10
to
thanks
do you know if powershell can check who access the network share on my
machine?

fschwiet

unread,
Jun 5, 2010, 6:52:23 PM6/5/10
to
Hi this is very useful. I was wondering how to discover that this property
is available, if you do not know about it in advance?

When I am looking for the property I want, I will do >> $gciResult | gm,
or I will do >> $gciResult | format-list. Using either of these techniques,
I found Name and PSPath but I could not find that Fullname is available.

Chris Dent

unread,
Jun 6, 2010, 4:29:09 AM6/6/10
to

fschwiet wrote:
> Hi this is very useful. I was wondering how to discover that this property
> is available, if you do not know about it in advance?
>
> When I am looking for the property I want, I will do >> $gciResult | gm,
> or I will do >> $gciResult | format-list. Using either of these techniques,
> I found Name and PSPath but I could not find that Fullname is available.
>
> "Al Fansome" wrote:

Get-Member should have shown it, although it depends a little on how you
built $gciResult.

For Format-List, adding * is often more useful as it overrides and
pre-defined list format.

e.g.

Get-ChildItem | Format-List *

Chris

Larry__Weiss

unread,
Jun 6, 2010, 10:00:56 AM6/6/10
to
On 6/6/2010 3:29 AM, Chris Dent wrote:
> For Format-List, adding * is often more useful as it overrides and
> pre-defined list format.
>

I'm constantly frustrated by PowerShell's fetish to constrain
host output to the current console width by truncation.

I'd love it if there was some way to tell PowerShell to just
intelligently wrap text output into a spreadsheet-like grid presentation
in the console, avoiding truncation.

I never find truncation useful.

- Larry

0 new messages