Powershell - 努力从可变位置复制文件
Powershell - Struggling to copy file from variable location
我一直在用 powershell 脚本敲我的脑袋,我已经尝试了几种不同的方法,想知道是否有人可以提供帮助?
目前不确定我是否只是在做一些愚蠢的事情,在此先感谢
目标:
要将 vbs 文件从用户的家庭驱动器复制到不同的位置,vbs 文件的位置会根据需要帐户管理员的用户进行更改,因此这需要可变。它从一个文本文件中获取位置,该文件包括要到达的确切路径和已经创建的用于将文件复制到的目标。
我目前遇到的问题:
$location = Get-Content C:\Users\Administrator\Desktop\here\drive4.txt | Out-String
$dest = "C:\Users\Administrator\Desktop\here"
Get-ChildItem -Path $location |
Copy-Item -Destination $dest -Recurse -Container -filter "peruser.vbs"
write-host $location
Read-Host -Prompt "Press Enter to continue or CTRL+C to quit"
问题
请看下面,我已经写主机来显示 powershell 试图到达的位置,作为旁注,我可以通过文件资源管理器很好地到达这个位置
Screenshot of error
收到错误
Get-ChildItem : Illegal characters in path.
At C:\Users\Administrator\Desktop\MapNetworkDrives2.ps1:17 char:1
+ Get-ChildItem -Path $location | Copy-Item -Destination $dest -Recurse -Container ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (\WIN-7V7GI0R7C...
:String) [Get-ChildItem], ArgumentException
+ FullyQualifiedErrorId : ItemExistsArgumentError,Microsoft.PowerShell.Commands.GetChildItemCommand
Get-ChildItem : Cannot find path '\WIN-7V7GI0R7CFK\homedrives\Onetest$
' because it does not exist.
At C:\Users\Administrator\Desktop\MapNetworkDrives2.ps1:17 char:1
+ Get-ChildItem -Path $location | Copy-Item -Destination $dest -Recurse -Container ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (\WIN-7V7GI0R7C...
:String) [Get-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
除非我误解了你 - 你只是想根据列表将文件复制到不同的位置。如果是这样,您只需要遍历列表即可。这对你有用吗?
$location = Get-Content "C:\Users\Administrator\Desktop\here\drive4.txt"
$dest = "C:\Users\Administrator\Desktop\here"
foreach ($loc in $location){
$vbs = (gci $loc -Filter "peruser.vbs").FullName
Copy-Item $vbs $dest -Force
}
你没有显示文本文件中的内容,迫使我们猜测,相对于试图帮助你而言,这并不是一件好事。所以,我假设它只是一个驱动器号或路径 UNC 的列表,这真的没有实际意义,因为你可以动态地提取它们,因此不需要文件。
我不明白你为什么要这样做...
Get-Content 'C:\Users\Administrator\Desktop\here\drive4.txt' |
Out-String
如果它只是一个供阅读的文本文件,你为什么要把它传送到任何地方?
你不需要双引号。单引号用于简单字符串,双引号用于变量扩展或其他特定格式要求
$dest = 'C:\Users\Adminstrator\Desktop\here'
直接传读就可以了
Get-Content 'C:\Users\Administrator\Desktop\here\drive4.txt' |
ForEach {
"Processing location $($PSItem.FullName)"
Copy-Item -Path $PSItem.FullName -Destination $dest -Filter 'peruser.vbs' -Recurse -WhatIf
}
注意事项:
您不需要 Write-Host 来输出到屏幕,因为这是 PowerShell 的默认设置,我将在后面的示例中展示。真的,除了用颜色写屏幕文字,你根本不需要用Write-Host/echo,好吧,还有一些特定的时间用它。
另外请注意,regarding Write-Host from the inventor of Monad/PowerShell Jeffery Snover
- http://www.jsnover.com/blog/2013/12/07/write-host-considered-harmful
- https://twitter.com/jsnover/status/727902887183966208
- https://docs.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Utility/Write-Information?view=powershell-5.1
您也不一定需要 Get-ChildItem 和 Copy-Item,因为两者都会递归地读取文件夹树。 正如我将在下面展示的那样。我正在使用 splatting 来收紧代码块以提高可读性。
因此,如果我仅使用系统上的驱动器和文件夹进行演示。逐步完成脚本构建,以确保在进入下一步之前我在每一步都得到了我期望的结果。
Get-PSDrive -PSProvider FileSystem |
Format-Table -AutoSize
<#
# Results
Name Used (GB) Free (GB) Provider Root CurrentLocation
---- --------- --------- -------- ---- ---------------
C 357.48 118.83 FileSystem C:\ Windows\system32
D 114.10 362.71 FileSystem D:\ Scripts
E 1194.00 668.89 FileSystem E:\
F 3537.07 188.83 FileSystem F:\
G FileSystem G:\
#>
# Validate if there is any content in the destination
Try
{
Get-PSDrive -PSProvider FileSystem |
Where Name -eq 'D' |
ForEach {
"Processing location $($PSItem.Root) and the contents are as listed."
(Get-ChildItem -Path 'D:\Temp\here' -Recurse).FullName
}
}
Catch {Write-Warning -Message 'No content in the destination folder'}
<#
# Results
Processing location D:\ and the contents are as listed.
WARNING: No content in the destination folder
#>
# Show what is on the drive for the source files
Get-PSDrive -PSProvider FileSystem |
Where Name -eq 'D' |
ForEach{
"Processing the location $($PSItem.Root)"
(Get-ChildItem -Path "$($PSItem.Root)\Temp\book1.csv" -Recurse).FullName
}
<#
# Results
Processing the location D:\
D:\Temp\Source\book1.csv
D:\Temp\book1.csv
#>
<#
# Show what will happen if a Copy files from the source to the destination occurs
Using splatting for readability
#>
Get-PSDrive -PSProvider FileSystem |
Where Name -eq 'D' |
ForEach{
"Processing the location $($PSItem.Root)"
$CopyItemSplat = @{
Path = "$($PSItem.Root)\Temp\book1.csv"
Destination = "$($PSItem.Root)\Temp\here"
Recurse = $true
WhatIf = $true
}
}
Copy-Item @CopyItemSplat
<#
# Results
Processing the location D:\
What if: Performing the operation "Copy File" on target "Item: D:\Temp\book1.csv Destination: D:\Temp\here\book1.csv".
If the results are as expected, execute the action
Using splatting for readability
#>
Get-PSDrive -PSProvider FileSystem |
Where Name -eq 'D' |
ForEach{
"Processing the location $($PSItem.Root)"
$CopyItemSplat = @{
Path = "$($PSItem.Root)\Temp\book1.csv"
Destination = "$($PSItem.Root)\Temp\here"
Recurse = $true
}
}
Copy-Item @CopyItemSplat
<#
# Results
Processing the location D:\
#>
# Validate if there is any content in the destination
Try
{
Get-PSDrive -PSProvider FileSystem |
Where Name -eq 'D' |
ForEach {
"Processing location $($PSItem.Root) and the contents are as listed."
(Get-ChildItem -Path 'D:\Temp\here' -Recurse).FullName
}
}
Catch {Write-Warning -Message 'No content in the destination folder'}
<#
# Results
Processing location D:\ and the contents are as listed.
D:\Temp\here\book1.csv
#>
我一直在用 powershell 脚本敲我的脑袋,我已经尝试了几种不同的方法,想知道是否有人可以提供帮助?
目前不确定我是否只是在做一些愚蠢的事情,在此先感谢
目标:
要将 vbs 文件从用户的家庭驱动器复制到不同的位置,vbs 文件的位置会根据需要帐户管理员的用户进行更改,因此这需要可变。它从一个文本文件中获取位置,该文件包括要到达的确切路径和已经创建的用于将文件复制到的目标。
我目前遇到的问题:
$location = Get-Content C:\Users\Administrator\Desktop\here\drive4.txt | Out-String
$dest = "C:\Users\Administrator\Desktop\here"
Get-ChildItem -Path $location |
Copy-Item -Destination $dest -Recurse -Container -filter "peruser.vbs"
write-host $location
Read-Host -Prompt "Press Enter to continue or CTRL+C to quit"
问题
请看下面,我已经写主机来显示 powershell 试图到达的位置,作为旁注,我可以通过文件资源管理器很好地到达这个位置
Screenshot of error
收到错误
Get-ChildItem : Illegal characters in path.
At C:\Users\Administrator\Desktop\MapNetworkDrives2.ps1:17 char:1
+ Get-ChildItem -Path $location | Copy-Item -Destination $dest -Recurse -Container ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (\WIN-7V7GI0R7C...
:String) [Get-ChildItem], ArgumentException
+ FullyQualifiedErrorId : ItemExistsArgumentError,Microsoft.PowerShell.Commands.GetChildItemCommand
Get-ChildItem : Cannot find path '\WIN-7V7GI0R7CFK\homedrives\Onetest$
' because it does not exist.
At C:\Users\Administrator\Desktop\MapNetworkDrives2.ps1:17 char:1
+ Get-ChildItem -Path $location | Copy-Item -Destination $dest -Recurse -Container ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (\WIN-7V7GI0R7C...
:String) [Get-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
除非我误解了你 - 你只是想根据列表将文件复制到不同的位置。如果是这样,您只需要遍历列表即可。这对你有用吗?
$location = Get-Content "C:\Users\Administrator\Desktop\here\drive4.txt"
$dest = "C:\Users\Administrator\Desktop\here"
foreach ($loc in $location){
$vbs = (gci $loc -Filter "peruser.vbs").FullName
Copy-Item $vbs $dest -Force
}
你没有显示文本文件中的内容,迫使我们猜测,相对于试图帮助你而言,这并不是一件好事。所以,我假设它只是一个驱动器号或路径 UNC 的列表,这真的没有实际意义,因为你可以动态地提取它们,因此不需要文件。
我不明白你为什么要这样做...
Get-Content 'C:\Users\Administrator\Desktop\here\drive4.txt' |
Out-String
如果它只是一个供阅读的文本文件,你为什么要把它传送到任何地方?
你不需要双引号。单引号用于简单字符串,双引号用于变量扩展或其他特定格式要求
$dest = 'C:\Users\Adminstrator\Desktop\here'
直接传读就可以了
Get-Content 'C:\Users\Administrator\Desktop\here\drive4.txt' |
ForEach {
"Processing location $($PSItem.FullName)"
Copy-Item -Path $PSItem.FullName -Destination $dest -Filter 'peruser.vbs' -Recurse -WhatIf
}
注意事项: 您不需要 Write-Host 来输出到屏幕,因为这是 PowerShell 的默认设置,我将在后面的示例中展示。真的,除了用颜色写屏幕文字,你根本不需要用Write-Host/echo,好吧,还有一些特定的时间用它。
另外请注意,regarding Write-Host from the inventor of Monad/PowerShell Jeffery Snover
- http://www.jsnover.com/blog/2013/12/07/write-host-considered-harmful
- https://twitter.com/jsnover/status/727902887183966208
- https://docs.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Utility/Write-Information?view=powershell-5.1
您也不一定需要 Get-ChildItem 和 Copy-Item,因为两者都会递归地读取文件夹树。 正如我将在下面展示的那样。我正在使用 splatting 来收紧代码块以提高可读性。
因此,如果我仅使用系统上的驱动器和文件夹进行演示。逐步完成脚本构建,以确保在进入下一步之前我在每一步都得到了我期望的结果。
Get-PSDrive -PSProvider FileSystem |
Format-Table -AutoSize
<#
# Results
Name Used (GB) Free (GB) Provider Root CurrentLocation
---- --------- --------- -------- ---- ---------------
C 357.48 118.83 FileSystem C:\ Windows\system32
D 114.10 362.71 FileSystem D:\ Scripts
E 1194.00 668.89 FileSystem E:\
F 3537.07 188.83 FileSystem F:\
G FileSystem G:\
#>
# Validate if there is any content in the destination
Try
{
Get-PSDrive -PSProvider FileSystem |
Where Name -eq 'D' |
ForEach {
"Processing location $($PSItem.Root) and the contents are as listed."
(Get-ChildItem -Path 'D:\Temp\here' -Recurse).FullName
}
}
Catch {Write-Warning -Message 'No content in the destination folder'}
<#
# Results
Processing location D:\ and the contents are as listed.
WARNING: No content in the destination folder
#>
# Show what is on the drive for the source files
Get-PSDrive -PSProvider FileSystem |
Where Name -eq 'D' |
ForEach{
"Processing the location $($PSItem.Root)"
(Get-ChildItem -Path "$($PSItem.Root)\Temp\book1.csv" -Recurse).FullName
}
<#
# Results
Processing the location D:\
D:\Temp\Source\book1.csv
D:\Temp\book1.csv
#>
<#
# Show what will happen if a Copy files from the source to the destination occurs
Using splatting for readability
#>
Get-PSDrive -PSProvider FileSystem |
Where Name -eq 'D' |
ForEach{
"Processing the location $($PSItem.Root)"
$CopyItemSplat = @{
Path = "$($PSItem.Root)\Temp\book1.csv"
Destination = "$($PSItem.Root)\Temp\here"
Recurse = $true
WhatIf = $true
}
}
Copy-Item @CopyItemSplat
<#
# Results
Processing the location D:\
What if: Performing the operation "Copy File" on target "Item: D:\Temp\book1.csv Destination: D:\Temp\here\book1.csv".
If the results are as expected, execute the action
Using splatting for readability
#>
Get-PSDrive -PSProvider FileSystem |
Where Name -eq 'D' |
ForEach{
"Processing the location $($PSItem.Root)"
$CopyItemSplat = @{
Path = "$($PSItem.Root)\Temp\book1.csv"
Destination = "$($PSItem.Root)\Temp\here"
Recurse = $true
}
}
Copy-Item @CopyItemSplat
<#
# Results
Processing the location D:\
#>
# Validate if there is any content in the destination
Try
{
Get-PSDrive -PSProvider FileSystem |
Where Name -eq 'D' |
ForEach {
"Processing location $($PSItem.Root) and the contents are as listed."
(Get-ChildItem -Path 'D:\Temp\here' -Recurse).FullName
}
}
Catch {Write-Warning -Message 'No content in the destination folder'}
<#
# Results
Processing location D:\ and the contents are as listed.
D:\Temp\here\book1.csv
#>