'Cannot find drive' powershell error after invoking Get-Date command - powershell

Why is it that this command is able to export and create a file in the current path but when I add the Get-Date cmdlet it suddenly fails?
Is the Get-Date cmdlet invoking some type of new environment?
Working command -
Get-Process | Sort-Object WorkingSet64 | Select-Object Name,#{Name='WorkingSet';Expression={($_.WorkingSet64/1MB)}} | Export-Csv -Path "processes64.csv" -Delimiter ","
Command breaks -
$Date = Get-Date -Format "MM-dd-yy-HH:MM"
Get-Process | Sort-Object WorkingSet64 | Select-Object Name,#{Name='WorkingSet';Expression={($_.WorkingSet64/1MB)}} | Export-Csv -Path "processes64$Date.csv" -Delimiter ","
Error message -
Export-Csv : Cannot find drive. A drive with the name 'processes64-06-28-16-15' does not exist.
At line:3 char:120
... Set64/1MB)}} | Export-Csv -Path "processes64-$Date.csv" -Delimiter ","
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : ObjectNotFound: (processes6406-28-16-15:String) [Export-Csv], DriveNotFoundException
FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.ExportCsvCommand
I'd just like to either export to a directory on the C drive or to the current working directory..

I believe I figured it out, it's because of the colon in the date format. File names can't have colons..
But I'm still curious as to what Powershell is interpreting, the error message doesn't seem to have anything to do with an invalid file name.

Related

Using powershell to read a file and split the text, but its throwing an error

I've written a powershell script to scan the network, and put those results into a file, sort and edit those results.
I can do all of that, except some of the pc names are coming back as NAME.DOMAIN.COM and others are just NAME, so I want to split the text, and just get the NAME.
However I'm getting this error for each line in the file:
You cannot call a method on a null-valued expression.
At C:\PowershellScripts\ComputerListV2.ps1:31 char:25
+ $text | Foreach-Object {$_.PCCOMPUTERNAMES.split(".")[0]} | Out-File ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Here is my script:
[System.Console]::Clear();
#Delete old output file
Write-Output "Removing old output file"
Remove-Item C:\PowershellScripts\ComputerListSorted.txt
#Declare IP range
$range = 1..254
$address = "192.168.0."
#status
Write-Output "Scanning active PCs"
#Scan ip range and get pc names
$range |
ForEach-Object {
Write-Progress 'Scanning Network' $address$_ -PercentComplete (($_ / $range.Count) * 100)
Start-Sleep -Milliseconds 100
Get-WmiObject Win32_PingStatus -Filter "Address='192.168.0.$_' and Timeout=200 and ResolveAddressNames='true' and StatusCode=0" |
Select-Object -Property #{Name="PCCOMPUTERNAMES";Expression={ [Net.DNS]::GetHostByAddress($_.Address).HostName+'.' }}
} | Out-File C:\PowershellScripts\ComputerList.txt
#Sort list
Write-Output "Sort list"
Get-Content -Path C:\PowershellScripts\ComputerList.txt | Sort-Object -Unique | Out-File C:\PowershellScripts\ComputerListRaw.txt
#Edit work file
Get-Content -Path C:\PowershellScripts\ComputerListRaw.txt | Select-Object -Skip 3 | Out-File C:\PowershellScripts\ComputerListEdited.txt
$text = Import-Csv C:\PowershellScripts\ComputerListEdited.txt
$text | Foreach-Object {$_.PCCOMPUTERNAMES.split(".")[0]} | Out-File C:\PowershellScripts\ComputerListEdited2.txt
#Rename file
Rename-Item -Path "C:\PowershellScripts\ComputerListEdited2.txt" -NewName "C:\PowershellScripts\ComputerListSorted.txt"
#Delete old output file
Write-Output "Removing work files"
Remove-Item C:\PowershellScripts\ComputerList.txt
Remove-Item C:\PowershellScripts\ComputerListRaw.txt
#Final statement
Write-Output "Final list in ComputerListSorted.txt"
Here is my sample file ComputerListEdited.txt:
NAME1.
NAME2.DOMAIN.COM
NAME3
NAME4
NAME5.DOMAIN.COM
As zett42 mentioned, your "Import-CSV" function is likely the cause. Running the same code on my computer outputs the error
You cannot call a method on a null-valued expression.
At line:1 char:25
$text | Foreach-Object {$_.PCCOMPUTERNAMES.split(".")[0]} | Out-File ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : InvalidOperation: (:) [], RuntimeException
FullyQualifiedErrorId : InvokeMethodOnNull
This is because using "Import-CSV" makes PowerShell treat the first line as the header.
NAME1.
-----
NAME2.DOMAIN.COM
NAME3
NAME4
NAME5.DOMAIN.COM
As the first line is "Name1.", this is the header value for the column of computer names. (Unfortunately, this means it is skipping the first computer as well). Changing this to Get-Content resolves this problem.
Additionally, you're referring to the columns as if they have a header PCCOMPUTERNAMES, which doesn't exist. Remove this reference as well to fix the problem. Try the below in its place.
$text = Get-Content C:\PowershellScripts\ComputerListEdited.txt
$text | Foreach-Object {$_.split(".")[0]} | Out-File C:\PowershellScripts\ComputerListEdited2.txt
A side note as well, you're getting info, exporting to a text file, then reading the text file, then deleting the text file. Keeping this information in a variable inside the script could lead to slightly better performance.

Auditing Permissions with Powershell

A little background first: I've been asked as part of a Scrum team at work to prepare a Powershell script that will collate a list of SMB Shares that have been flagged as safe to archive from the CSV files that were given to me nested in a folder structure (each share equates to one CSV file, with a list of files within, but the only relevance for this is that they are titled SHARENAME.csv), and the current permissions of each, in case they need to be restored at a later date.
At the moment, I have the following for the first step (nice and easy):
get-childitem -path 'C:\users\adam.lane\desktop\_with adam\_remove' | select BaseName | export-csv -path "..\test.csv"
This gives me a single CSV file with the names of all of the 188 shares in a single column. The second step, exporting a CSV file for each with a list of permissions, is not going as well. So far I have the following:
$share = Import-Csv -path 'C:\users\adam.lane\desktop\_with adam\test.csv' -Header 'BaseName'
ForEach ($share in $share) {
get-smbshareaccess -name $share -cimsession euukpopdfs005
}
Obviously at the moment there's no export-csv command in there, but essentially I'll want the script to use the same share name that it calls with 'get-smbshareaccess -name' as the file name for the CSV file. Unfortunately I hit 188 errors in the following format at this point:
get-smbshareaccess : euukpopdfs005: No MSFT_SMBShare objects found with property 'Name' equal to '#{BaseName=Brand}'. Verify the value of the property and retry.
At line:3 char:1
+ get-smbshareaccess -name $share -cimsession euukpopdfs005
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (#{BaseName=Brand}:String) [Get-SmbShareAccess], CimJobException
+ FullyQualifiedErrorId : CmdletizationQuery_NotFound_Name,Get-SmbShareAccess
+ PSComputerName : euukpopdfs005
So rather than calling the BaseName (for instance "Brand" in this first case), it's calling (#{BaseName=Brand}:String), which it then doesn't find anything for.
Is there anyway I can tidy this up? Ideally in some way that will work for both the Get-SmbShareAccess command and the export-csv command, but I'm not against doing a little more jiggery pokery as needed.
This is my first post, so I apologise if this is too long, lacking in detail, etc etc. Let me know if you need anything else! Thanks in advance.
Final (working) code after suggestions:
get-childitem -path 'C:\users\adam.lane\desktop\_with adam\_remove' | select BaseName | export-csv -path "..\test.csv"
$share = Import-Csv -path 'C:\users\adam.lane\desktop\_with adam\test.csv' -Header 'BaseName'
$share | Format-List
ForEach ($item in $share) {
get-smbshareaccess -name $item.BaseName -cimsession euukpopdfs005
}
Final working code (Thanks everyone!):
get-childitem -path 'C:\users\adam.lane\desktop\_with adam\_remove' | select BaseName | export-csv -path "..\test.csv"
$share = Import-Csv -path 'C:\users\adam.lane\desktop\_with adam\test.csv' -Header 'BaseName'
$share | Format-List
ForEach ($item in $share) {
get-smbshareaccess -name $item.BaseName -cimsession euukpopdfs005
}

Trying pipe in a list of CSV in to import CSV

So I am trying to pipe in a file list into import CSV:
ls *.csv | select FullName | where FullName -NotMatch "fixed" | ForEach-Object {
Import-Csv -Path %($_.FullName) -Delimiter ";"
}
But I am getting this error:
Import-Csv : A positional parameter cannot be found that accepts argument
'C:\***\Documents\Daraz Order\order.list.export 2019-11-13.csv'.
At line:2 char:1
+ Import-Csv -Path %($_.FullName) -Delimiter ";"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Import-Csv], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.ImportCsvCommand
It gives the same error for all the files in the list. I have tried the ToString() method. But the error persist:
+ Import-Csv -Path %($_.FullName.ToString()) -Delimiter ";"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Import-Csv], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.ImportCsvCommand
What might be causing this?
The answer Patrick gave you is correct. However you still get the error. You should try different methods of troubleshooting (using Powershell_ISE obviously).
$import = #()
ls *.csv| select FullName | where FullName -NotMatch "fixed" | foreach-object {
$path = $_.FullName
$path.GetType()
$path
try{
Get-Content -Path $path
}catch{
Write-Host "Path does not exist"
}
$import += Import-Csv -path $path -delimiter ";"
}
In the above example, to make sure we don't get distracted, we put all the content in the import array. Next look at the path, does it exist? Can you obtain the content of the file? Let's look at the type of the file by trying .GetType().
The error basically says that Import-CSV does not except your argument. So try fixing Import-CSV with a valid path to see if you get it to work first.
PS: Your script does actually work on my system (PowerShell 5.1).
It seems some idiosyncrasy of PowerShell 6. I just decided to use a code block and just pipes. The code that worked for me was:
ls *.csv| select FullName,BaseName | where FullName -NotMatch "fixed"| foreach {
$file = $_.FullName.ToString()
$bname = $_.BaseName.ToString()
$bnamepath = ".\$bname-fixed.csv"
Import-Csv $file -Delimiter ';' | Export-Csv $bnamepath -Delimiter ','
}
I still had to do a pipe at the end because keeping the data in a variable causes the output file just have the object properties and not the values of the other CSV. This script will work if you wan to process the files in Excel without changing your system's locale.

Comparing two CSV files in powershell and creating an output

I'm currently working on a script to import 2 csv files, compare the fqdn columns and output the results to a file.
The issue is after many hours of testing I'm at the point that it looks like my script is working up until the point of getting the path for each file that needs to be imported but I can't seem to get the import-csv command to do what I need it to.
I'd appreciate any guidance you can provide.
My script so far and the error I'm getting are below:
$CMDB_Installed = Get-ChildItem -Path C:\Users\nha1\Desktop\Reports\CMDBInstall | Sort CreationTime -Descending | Select -expa FullName -First 1 | Out-String
$SCOM_AgentList = Get-ChildItem -Path C:\Users\nha1\Desktop\Reports\SCOMUAT | Sort CreationTime -Descending | Select -expa FullName -First 1 | Out-String
$SL = Import-Csv $SCOM_AgentList
$CL = Import-Csv $CMDB_Installed
Compare-Object -ReferenceObject $CL -DifferenceObject $SL -Property fqdn |
Export-Csv -NoTypeInformation -Path = C:\Users\nha1\Desktop\Reports\AuditOutput\UATNeedsAgent+SCOM\UATHosts-NotinSCOM$(get-date -format yyyy-MM-dd).csv
Error Message:
import-csv : Illegal characters in path.
At line:4 char:7
+ $SL = import-csv $SCOM_AgentList
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OpenError: (:) [Import-Csv], ArgumentException
+ FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.ImportCsvCommand
import-csv : Illegal characters in path.
At line:5 char:7
+ $CL = import-csv $CMDB_Installed
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OpenError: (:) [Import-Csv], ArgumentException
+ FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.ImportCsvCommand
$CMDB_Installed = ... | Select -expa FullName -First 1 | Out-String
Don't use Out-String, unless you want a for-display, multi-line string representation.
Your file-path variables therefore contain newlines (line breaks), which Import-Csv complains about, given that newlines in file names are illegal in NTFS (on Windows).
Simply omit the Out-String call, given that Select -expa FullName -First 1 by definition already outputs a string (given that the .FullName property on the objects output by Get-ChildItem is [string]-typed).
To recreate the problem:
PS> Import-Csv "foo`n" # illegal line break in file path
Import-Csv : Illegal characters in path.
To demonstrate that Out-String produces a multi-line string even with a single-line string as input:
PS> ('foo' | Out-String).EndsWith("`n")
True

Powershell - Export Multiple CSV's into unique folders

I have been working on a PowerShell script for the better part of well a week or two. I've been able to get some parts of it working however I'm unable to fully get this automated.
I deal with a lot of CSV files on a daily basis, I have been tasked with uploading them into our software however sometimes they're too large to handle so I break them down based upon their "type" (it's a column in the CSV) and I export it to a single CSV per "type". I've been able to accomplish this with the following:
$file = gci -Filter "*.csv";
Import-Csv $file `
| Group-Object –Property “type” `
| Foreach-Object `
{
$path=$_.name+”.csv” ; $_.group `
| Export-Csv –Path $path –NoTypeInformation
}
So this works wonderfully, for each individual CSV. Unfortunately I don't have the time to do this for each individual CSV. Now I come to my other PowerShell script:
get-childitem -Filter "*.csv" `
| select-object basename `
| foreach-object{ $path=$_.basename+".csv" #iterate through files.
if(!(Test-Path -path $_.basename)) #If the folder of the file can't be found then it will attempt to create it.
{
New-Item $_.basename -type directory; $file=$_.basename+".csv";
Import-Csv $file `
| Group-Object -Property "Type" `
| Foreach-Object {
$path=$_.name+".csv"; $_.group `
| `
if(!(Test-Path -path $path2))
{
New-Item $path2 -type directory
Export-Csv -Path $path2 + "\" + $path -NoTypeInformation
}
else
{
"Failed on: " + $_.basename
#Export-Csv -Path $_.basename + "\" + $path -NoTypeInformation
}
}
}
else
{
Import-Csv $path `
| Group-Object -Property "Type" `
| Foreach-Object {$path=$_.basename+".csv" ; $_.group
if(Test-Path -path $._)
{
New-Item $path2 -type directory
Export-Csv -Path $path2 + "\" + $path -NoTypeInformation
}
#else
#{
Write-Host "Failed on: $_.basename"
#Export-Csv -Path $_.basename + "\" + $path -NoTypeInformation
#}
}
}
}
I just can't wrap my head around "why" this isn't working effectively. I have two conditionals. Is there a folder for the CSV? If no create one. I have to have another one because one of the "types" contains a \ which errors out if I don't have the folder, so I automatically try to create it. When I run the script I get the Path is null.
The Error is:
The term ' ' is not recognized as the name of a cmdlet, function,
script file, or operable program. Check the spelling of the name, or
if a path was included, verify that the path is correct and try again.
At C:\Users\c.burkinshaw\foldermake.ps1:11 char:26
+ | ` <<<<
+ CategoryInfo : ObjectNotFound: ( :String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Test-Path : Cannot bind argument to parameter 'Path' because it is null.
At C:\Users\c.burkinshaw\foldermake.ps1:12 char:45
+ if(!(Test-Path -path <<<< $path2))
+ CategoryInfo : InvalidData: (:) [Test-Path], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.TestPathCommand
Any help would be greatly appreciated, if you have questions please don't hesitate to ask.
You have not defined $path2 anywhere, so something like test-path -path $path2 will say path is null. And in one place you are using $._ which will again give errors.
Edit after question updated with error message:
Your error message also says the same
Test-Path : Cannot bind argument to parameter 'Path' because it is
null. At C:\Users\c.burkinshaw\foldermake.ps1:12 char:45
+ if(!(Test-Path -path <<<< $path2))
Also the other error is in:
$path=$_.name+".csv"; $_.group `
| `
what are you trying to do here with the $_.group?
It is not proper. You cannot do $_.group | and provide some if statement.
Other comments:
Why are using $_.basename and then appending .csv? You could have just used $_.name. Try to not use the select-object basename - I don't see the value.
Extract the common import-csv and export-csv part into a function.