【问题标题】:Rename-Item : Object reference not set to an instance of an objectRename-Item : 对象引用未设置为对象的实例
【发布时间】:2014-06-11 15:31:57
【问题描述】:

我有一个我一直在处理的脚本,它读取指定的目录,定位多个 .CSV 文件,并为每个 .CSV 文件执行一些逻辑并最终将它们重命名为 .csv.archived 。我试图尽可能干净地处理这个问题,但我弄得一团糟。

手头的问题是,我似乎无法弄清楚如何将单个文件名传递给字符串以重命名现有文件。该过程循环正常,文件最终被重命名,但出现以下错误:

#set the location where the .CSV files will be pulled from
$Filecsv = get-childitem "\\SERVER\Audit Test\" -recurse | where {$_.extension -eq ".csv"} | % {
$_.Name
}

在上面的代码中,我的想法是 $_.Name 是我(相信我)提取每个文件的文件名的地方。在下一个块的末尾,文件用文件名重命名。

#for each file found in the directory
ForEach ($item in $Filecsv) {

 #count the times we've looped through
 "Iterations : " + $iterations


# get the date and time from the system
$datetime = get-date -f MMddyy-hhmmtt
# rename the file 
rename-item -path ("\\SERVER\Audit Test\" + $_.Name ) -newname ($filename + $datetime + ".csv.archived")
$iterations ++

}

我认为这个过程在这里很有趣:

rename-item -path ("\\SERVER\Audit Test\" + $_.Name )

出于测试目的,我已经删除了不相关的代码,如果有人能告诉我我做错了什么并且我没有疯,我会很高兴。

我不确定我是否正确理解 ForEach 循环的工作方式,TechNet 提供帮助:http://social.technet.microsoft.com/Forums/en-US/e8da8249-ea91-4772-ae85-582a4b37425b/powershell-foreachobject-vs-foreach?forum=smallbusinessserver

但没有回答我的特定问题。

有人想了解一下吗?

谢谢!这是完整的脚本:

$iterations = 1

#set the location where the .CSV files will be pulled from
$Filecsv = get-childitem "\\SERVER\Audit Test\" -recurse | where {$_.extension -eq ".csv"} | % {
$_.Name
}

#check to see if files exist, if not exit cleanly 


#for each file found in the directory
ForEach ($item in $Filecsv) {



 #count the times we've looped through
 "Iterations : " + $iterations


# get the date and time from the system
$datetime = get-date -f MMddyy-hhmmtt
# rename the file 
rename-item -path ("\\SERVER\Audit Test\" + $_.Name ) -newname ($_.Name + $datetime + ".csv.archived")
$iterations ++

}

【问题讨论】:

  • $_ 不应该是 $item 吗?

标签: string powershell foreach


【解决方案1】:

如果是我,我会将文件作为对象来处理,而不仅仅是名称的字符串。所以我会做这样的事情:

#set the location where the .CSV files will be pulled from
$Filecsv = get-childitem "\\SERVER\Audit Test\" -recurse | where {$_.extension -eq ".csv"} 

#for each file found in the directory
ForEach ($item in $Filecsv) {

 #count the times we've looped through
 "Iterations : $iterations"


# get the date and time from the system
$datetime = get-date -f MMddyy-hhmmtt
# rename the file 
$NewName = $item.fullname -replace ".csv$","$datetime.csv.archived"
$Item.MoveTo($NewName)
$iterations ++

}

这需要每个文件,通过将末尾的 .csv 替换为您想要的 $datetime.csv.archived 来设置一个新名称,然后将文件移动到有效地重命名它的新名称。

此外,如果您希望每个项目的 Name 属性而不是 ForEach{$_.Name},您最好使用 Select -Expand Name

【讨论】:

  • 你的方式似乎更有意义,我会用我的其余代码尝试这种方式,看看我是否不能让它更容易管理。谢谢!你总是为我而来@TheMadTechnician
  • 完美无瑕。再次感谢。这更容易使用!
【解决方案2】:

这对我有用,我将 $_.Name 更改为 $item(此时它是一个字符串,因此没有 name 属性)并且它有效

$iterations = 1

#set the location where the .CSV files will be pulled from
$Filecsv = get-childitem "c:\AuditTest\" -recurse | where {$_.extension -eq ".csv"} | % {
$_.Name
}

#check to see if files exist, if not exit cleanly 


#for each file found in the directory
ForEach ($item in $Filecsv) 
{

     #count the times we've looped through
     "Iterations : " + $iterations


    # get the date and time from the system
    $datetime = get-date -f MMddyy-hhmmtt
    # rename the file 
    rename-item -path ("c:\AuditTest\" + $item ) -newname ("c:\AuditTest\" + $item + $datetime + ".csv.archived")
    $iterations ++

}

具体取决于你在做什么,虽然我会像这样改变它

$Filecsv = get-childitem "c:\AuditTest\" -recurse | where {$_.extension -eq ".csv"}

这将为您提供实际的文件对象,而不是一个字符串,在解析名称等方面为您提供更多选项。

【讨论】:

  • 完美运行!它总是小事。
猜你喜欢
  • 2017-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-20
相关资源
最近更新 更多