Powershell:Get-ChildItem - 管道重命名项和复制项

时间:2016-12-16 15:00:40

标签: powershell

我正在尝试编写一个收集服务器名称列表的脚本,然后遍历每个服务器名称并将第二个文件夹抓取到目录中的最新文件夹,重命名并将其复制到另一个服务器。我在使用一个命令完成所有工作时遇到了麻烦,我不确定将它拆分并使其正常工作的最佳方法是什么。我在尝试不同的事情时遇到错误,主要是“rename-item:无法评估参数”NewName“因为它的参数被指定为脚本块并且没有输入”。以下是导致此错误的代码段:

$serverNames = Get-Content -Path "C:\servers.txt"

foreach ($serverName in $ServerNames) {

$reportServer = "a56741035"  

Get-ChildItem "\\$($serverName)\d$\mposlogs\device" | where {  $_.PSIsContainer } | Sort CreationTime -Descending | Select -Skip 1 | Select -First 1 | Rename-Item -NewName { "$serverName" + "_" + $_.Name } | Copy-Item $_.FullName -Destination "\\$($reportServer)\c$\temp\mpos\logs" }

另一个是“无法将参数绑定到参数'Path',因为它为null”。以下是导致此错误的代码:

$serverNames = Get-Content -Path "C:\servers.txt"

foreach ($serverName in $ServerNames) {

$reportServer = "a56741035"  

Get-ChildItem "\\$($serverName)\d$\mposlogs\device" | where {  $_.PSIsContainer } | Sort CreationTime -Descending | Select -Skip 1 | Select -First 1 | ForEach-Object { Rename-Item -NewName { "$serverName" + "_" + $_.Name } | Copy-Item $_.FullName -Destination "\\$($reportServer)\c$\temp\mpos\logs" } }

我觉得我很亲密,只是看不到什么。非常感谢任何帮助,非常感谢你。祝你有美好的一天。

已包含最新代码:

 Get-ChildItem "\\$($serverName)\d$\mposlogs\device" | where {  $_.PSIsContainer } | Sort CreationTime -Descending | Select -Skip 1 | Select -First 1 | ForEach-Object { Rename-Item -Path $_.FullName -NewName ( "$serverName" + "_" + $_.Name ) ; Copy-Item $_.FullName -Destination "\\$($reportServer)\c$\temp\mpos\logs" } 

最新评论的代码:

Get-Child-Item "\\$serverName\d$\mposlogs\device" | where {$_.PSIsContainer} | Sort CreationTime -Descending | Select -Skip 1 | Select -First 1 | ForEach-Object { Rename-Item -Path $_.FullName -NewName ( "$serverName" + "" + $.Name ) ; Copy-Item ( "$serverName" + "" + $.Name ) -Destination "\\$reportServer\c$\temp\mpos\logs" } 

3 个答案:

答案 0 :(得分:2)

所以事实证明这比我想象的要困难,诀窍是Rename-Item似乎基本上消耗了流水线对象而没有给你机会在后续名称中使用该对象(使用scriptblock是也不是很理想,更容易使用简单的连接字符串)所以你需要稍微改变你的循环的Rename-Item部分

Rename-Item -Path $_.FullName -NewName ("$serverName" + "_" + $_.Name)

就语法变化而言,prageeth建议您可以制作它们但是它们不需要并且会增加歧义(Get-Childitem不需要转义字符来访问管理员共享,并且使用$($)语法没有任何问题即使没有访问财产)。

修改

好的,稍后在评论中工作,这是完整GCI管道的更新版本。我在我的环境中成功测试了它,所以手指交叉它适合你。如果它的任何部分没有意义,请告诉我。

Get-ChildItem "\\$serverName\d$\mposlogs\device" | where {$_.PSIsContainer} | Sort CreationTime -Descending | Select -Skip 1 | Select -First 1 | ForEach-Object { Rename-Item -Path $_.FullName -NewName ( "$serverName" + "_" + $_.Name ) -PassThru | Copy-Item  -Destination "\\$reportServer\c$\temp\mpos\logs" }

答案 1 :(得分:0)

修改

正如用户迈克所提到的,管理员分享似乎不需要使用$进行转义。真正的问题是rename-Item cmdlet缺少-Path参数。谢谢你带来迈克!

但是我仍然建议删除额外$ $ $($ serverName)以减少歧义。

试试这个!

Get-ChildItem "\\$serverName\d$\mposlogs\device" | where {  $_.PSIsContainer } | Sort CreationTime -Descending | Select -Skip 1 | Select -First 1 | ForEach-Object { Rename-Item -Path $_.FullName -NewName { "$serverName" + "_" + $_.Name } | Copy-Item $_.FullName -Destination "\\$reportServer\c$\temp\mpos\logs" } }

答案 2 :(得分:0)

在这样的情况下,最好先分析命令输出......

# Rename doesn't output anything by default
Rename-Item ToBeRenamed.txt Renamed.txt

# For most commands with that default behaviour, you can use -PassThru to force output
Rename-Item ToBeRenamed.txt Renamed.txt -PassThru

# Once we have something in the pipeline, we can pipe result to Copy-Item
Rename-Item ToBeRenamed.txt Renamed.txt -PassThru | Copy-Item -Destination C:\temp
ls C:\temp\Renamed.txt

我建议在这里避免使用ForEach-Object - 这不是真正需要的。你只需要控制命令的输出,就是这样。