Export-CSV with the output path as a variable - powershell

Is there a way I can export the list to a text file and separate them by share name somehow, not single file?
I'd like to do in this format, "$hostname-$sharename.txt".
Here is what I have so far:
$Shares = Get-WmiObject Win32_Share -Filter "not name like '%$'" |
Select-Object -Expand Path
$re = ($Shares | ForEach-Object {[Regex]::Escape($_)}) -join '|'
$results = foreach ($Share in $Shares) {
(Get-ChildItem $Share -Recurse | Select-Object -Expand FullName) -replace "^($re)\\"
}
$results | Out-File -FilePath "C:\Output\$($env:computername)-$sharename.txt"

If I understand the question correctly, all you are missing in your code is the sharename part for the various output files.
Below will hopefully do what you want:
$outputDir = 'C:\Output'
$Shares = Get-WmiObject Win32_Share -Filter "not name like '%$'"
$re = ($Shares | ForEach-Object {[Regex]::Escape($_.Path)}) -join '|'
foreach ($Share in $Shares) {
$result = (Get-ChildItem -Path $Share.Path -File -Recurse | Select-Object -Expand FullName) -replace "^($re)\\"
# output the results per share in a text file
$fileOut = Join-Path -Path $outputDir -ChildPath ('{0}-{1}.txt' -f $env:COMPUTERNAME, $Share.Name)
$result | Out-File -FilePath $fileOut -Force
}

Related

command 'search-index' does not appear to be working

here is the script I've created. I have downloaded the 'PSSearch' package and when I goto commands 'Search-Index' is one of the available commands
$computers = #([some computer])
$destination = "[some path]"
foreach ($computer in $computers) {
$Path = Set-Location [path on computer]
$keywords= #('"word 1"','word2','word3','word4')
$dirlist = Get-ChildItem -Recurse -Force $Path -ErrorAction Continue
foreach($word in $keywords) {
$SearchResults = Search-Index $word
$dirlist | Where-Object {$_.Name -match $SearchResults} | Select-Object Name,FullName | format-Table * -AutoSize |
Export-Csv $destination\FoundFiles.csv -nti -Append
$cui = ($dirlist | Where-Object {$_.Name -match $SearchResults})
Copy-Item $cui -Destination $destination - Append
}
}
What is happening is I'm getting all files and folders from the location (not just the ones I'm searching for)
The problem could be that I don't know how this line should be scripted
$cui = ($dirlist | Where-Object {$_.Name -match $SearchResults})

How to make Powershell to output the result to a csv

I am trying to output to a csv file the result that I am getting from "Get-ChildItem"
I need to save only the LastWriteTime and the Name.
This is the Get-ChildItem output
I am trying something like
$pc = Get-WmiObject Win32_ComputerSystem
$file = Get-ChildItem -Path S:\Docker\RCT\repo\*xml -Recurse -Force
$DeviceObj = New-Object PSObject -Property #{
DeviceName = $pc.Name
FileName = $file.Name
FileDate = $file.LastWriteTime
}
$DeviceObjList += $DeviceObj
$DeviceObjList | Export-Csv -Path "$current_path\FileStatus.csv" -NoTypeInformation -Encoding UTF8
But my csv is not saving the file name and also the timestamp
Use a ForEach-Object to loop though your $file object
$pc = Get-WmiObject Win32_ComputerSystem
$file = Get-ChildItem -Path S:\Docker\RCT\repo\*xml -Recurse -Force
$file | ForEach-Object {
$DeviceObj = New-Object PSObject -Property #{
DeviceName = $pc.Name
FileName = $_.Name
FileDate = $_.LastWriteTime
}
$DeviceObjList += $DeviceObj
}
$DeviceObjList | Export-Csv -Path "$current_path\FileStatus.csv" -NoTypeInformation -Encoding UTF8
..but in fact, this is more efficient:
$pc = Get-WmiObject Win32_ComputerSystem
$file = Get-ChildItem -Path S:\Docker\RCT\repo\*xml -Recurse -Force
$DeviceObjList = $file | ForEach-Object {
[pscustomobject]#{
DeviceName = $pc.Name
FileName = $_.Name
FileDate = $_.LastWriteTime
}
}
$DeviceObjList | Export-Csv -Path "$current_path\FileStatus.csv" -NoTypeInformation -Encoding UTF8
You Don't need WMI to get the computer name, use the built-in variable $env:COMPUTERNAME
Use Calculated Properties to add the Computer name to the results.
Iteration not required here, just add the Export-Csv to the pipeline
So you can do that:
$file = Get-ChildItem -Path S:\Docker\RCT\repo\*xml -Recurse -Force
$File | Select #{N="DeviceName";E={$env:COMPUTERNAME}},Name,LastWriteTime |
Export-Csv -Path "$current_path\FileStatus.csv" -NoTypeInformation -Encoding UTF8
And if you want to make it shorter, you can use aliases and don't define any variables
gci S:\Docker\RCT\repo\*xml -R -Fo |
select #{N="DeviceName";E={$env:COMPUTERNAME}},Name,LastWriteTime |
epcsv "$current_path\FileStatus.csv" -NoT -En UTF8

Count the number of files in the directory as well as the number of folders

Currently , I can export the list to a text file and separate them by share name.
My question is : I want to be able to count the number of files in the directory as well as the number of folders into a separate text file.
I'd like to do in this format for text file , $hostname-$sharename-count.txt
For example:
My desired output:
1000 #Folder count
150 #File count
Here is what I have so far:
$outputDir = 'C:\Output'
$Shares = Get-WmiObject Win32_Share -Filter "not name like '%$'"
$re = ($Shares | ForEach-Object {[Regex]::Escape($_.Path)}) -join '|'
foreach ($Share in $Shares) {
$result = (Get-ChildItem -Path $Share.Path -File -Recurse | Select-Object -Expand FullName) -replace "^($re)\\"
# output the results per share in a text file
$fileOut = Join-Path -Path $outputDir -ChildPath ('{0}-{1}.txt' -f $env:COMPUTERNAME, $Share.Name)
$result | Out-File -FilePath $fileOut -Force
}
You can simply expand the code you have like below:
$outputDir = 'C:\Output'
$Shares = Get-WmiObject Win32_Share -Filter "not name like '%$'"
$re = ($Shares | ForEach-Object {[Regex]::Escape($_.Path)}) -join '|'
foreach ($Share in $Shares) {
$files = (Get-ChildItem -Path $Share.Path -File -Recurse | Select-Object -Expand FullName) -replace "^($re)\\"
# output the list of files per share in a text file
$fileOut = Join-Path -Path $outputDir -ChildPath ('{0}-{1}.txt' -f $env:COMPUTERNAME, $Share.Name)
$files | Out-File -FilePath $fileOut -Force
# output the count results for files and folders per share in a text file
$folders = Get-ChildItem -Path $Share.Path -Directory -Recurse
$content = 'Folders: {0}{1}Files: {2}' -f $folders.Count, [Environment]::NewLine, $files.Count
$fileOut = Join-Path -Path $outputDir -ChildPath ('{0}-{1}-count.txt' -f $env:COMPUTERNAME, $Share.Name)
$content | Out-File -FilePath $fileOut -Force
}
P.S. You can add switch -Force to the Get-ChildItem cmdlet to also get the hidden or system files listed if there are any such files inside the shares
If you just want to have a count, you could do something like this:
$resultForFiles = (Get-ChildItem -Path $Share.Path -File -Recurse | Select-Object -Expand FullName)
$resultForFolders = (Get-ChildItem -Path $Share.Path -Directory -Recurse | Select-Object -Expand FullName)
$resultForFiles.Count | Out-File "Path" -Append
$resultForFolders.Count | Out-File "Path" -Append
The -File switch for Get-ChildItem will only get files and the -Directory will only get folders
You can do this in just one line of code
Get-ChildItem | Measure-Object -Property Mode
The property Mode from Get-ChildItem tells you if you are getting folders, files or others.
You can also use get-help Measure-Object -Examples to check some useful examples on measuring files and folders

How to output multiple file extensions stored in a .txt file on Powershell

my purpose is to output the files with the extensions that match the ones I store on a .txt file but I don't know how to make it work. The way I am trying to do now does not generate any output or output the files of the extensions that are not on the text file (Extension.txt) I indicate. How am I supposed to fix this?
The content in my .txt file is:
*.xlsx,*.xlsm,*.xlsb,*.xltx,*.xltm,*.xls,*.xml
My current code is as followed:
$fileHeaders = #('country','cDrive','dDrive')
$extensions = ${C:temp:Extension.txt}
$LocContent = Import-Csv "C:\temp\Location.txt" -Header $fileHeaders
$NumberOfDays = Read-Host 'Within how many days the files created would you like to output?'
$SizeOfFile = Read-Host 'Above what size of the files would you like to output (in kb or mb)?'
$Output = ForEach($Row in $LocContent){
if (($Row.country -ne $null) -and ($Row.cDrive -ne $null) -and ($Row.dDrive -ne $null)){
Get-ChildItem $Row.cDrive,$Row.dDrive -Force -Include -Recurse |
$extensions Where-Object LastWriteTime -gt (Get-Date).AddDays(-$NumberOfDays) |
Where-Object {$_.length/$SizeOfFile -gt 1} |
Select-Object -Property #{N='File Basename';E={$_.BaseName}},
#{N='File Extension';E={$_.Extension}},
#{N='size in MB';E={$_.Length/1024kb}},
Directory,
CreationTime,
LastWriteTime,
#{N="Location";E={$Row.country}}
}
$Output | Format-Table -Auto
$Output | Out-Gridview
$Output | Export-Csv '\NewData.csv' -NoTypeInformation
This both generated the files, outputs the files and makes sure they are in your .txt file.
I am not surprised your code wont work. You were doing it fairly poorly. Look forward to seeing you improve.
$extensions = ((Get-Content C:\temp\Extensions.txt) -join ',') -split ',' -replace '\*',''
Foreach($ext in $extensions){
Get-ChildItem "C:\temp" -Recurse | select Name, FullName, CreationTime, Extension | Where-Object {$_.Extension -like $ext} | export-csv C:\Files.csv -NoTypeInformation -append
}
I just cleaned up your code.
Without knowing the content of Location.txt,
if there are repetitions in the drives, wouldn't Output contain dublettes of the files with different country?
Without your environment untested.
## Q:\Test\2018\07\05\SO_51183354.ps1
$fileHeaders = #('country','cDrive','dDrive')
$Extensions = (Get-Content 'C:\temp\Extension.txt') -replace '\*' -split ','
$LocContent = Import-Csv "C:\temp\Location.txt" -Header $fileHeaders |
Where-Object {($_.country -ne $null) -and
($_.cDrive -ne $null) -and
($_.dDrive -ne $null) }
$NumberOfDays = Read-Host 'Max file age in days?'
$SizeOfFile = Read-Host 'Min file size (in kb or mb)?'
$FileAge = (Get-Date).AddDays(-$NumberOfDays)
$Output = ForEach($Row in $LocContent){
Get-ChildItem $Row.cDrive,$Row.dDrive -Force -Recurse |
Where-Object {($_.Extension -in $Extensions) -and
($_.LastWriteTime -gt $FileAge) -and
($_.Length -gt $SizeOfFile) } |
Select-Object -Property `
#{N='File Basename' ;E={$_.BaseName}},
#{N='File Extension';E={$_.Extension}},
#{N='size in MB' ;E={$_.Length/1MB}},
Directory,
CreationTime,
LastWriteTime,
#{N="Location" ;E={$Row.country}}
}
$Output | Format-Table -Auto
$Output | Out-Gridview
$Output | Export-Csv '\NewData.csv' -NoTypeInformation

Powershell : Get directory permission recursively

I am trying to get the CSV output like below so that user can filter in excel.
Folder,Group,Permission
I:\Folder1,corp\group1,ReadData,ExecuteFile,Synchronize
I:\Folder1\Folder2,corp\group2,ReadData,ExecuteFile,Synchronize
Below is what is started with. Very inefficient and does not give the desired CSV output. Will appreciate any help.
$output_file = $(get-date -f MM-dd-yyyy_HH_mm_ss)+'.txt'
"{0},{1},{2}" -f "Folder","Groups","Permissions"| add-content -path $output_file
$file_content = ''
function GetFolders($path = $pwd)
{
if( $path -ne $null) {
$new_row = Get-ACL $path | select -ExpandProperty Access | Where-Object IdentityReference -Like "CORP*" | SELECT $path, IdentityReference, FileSystemRights | Format-Table -HideTableHeaders | Out-String
$fileContent += $new_row
$fileContent | add-content -path $output_file
foreach ($item in Get-ChildItem $path)
{
if (Test-Path $item.FullName -PathType Container)
{
Write-Output $item.FullName
GetFolders $item.FullName
$new_row = Get-ACL $item.FullName | select -ExpandProperty Access | Where-Object IdentityReference -Like "CORP*" | SELECT $item.FullName, IdentityReference, FileSystemRights | Format-Table -HideTableHeaders | Out-String
$fileContent += $new_row
$fileContent | add-content -path $output_file
}
}
}
}
GetFolders "J:\"
You were on the right path but went off-course a bit.
Set-Content -Path $FileName -Value 'Folder,Groups,Permissions'
(Get-Acl -Path $Path).Access |
Where-Object -Property IdentityReference -like 'corp*' |
ForEach-Object {
Add-Content -Path $FileName -Value "$Path,$($_.IdentityReference),$($_.FileSystemRights -replace '\s')"
}
To be a little more fancy (if you want to edit the code in the subexpressions or something of that nature)
$Val = {"$Path,$($_.IdentityReference),$($_.FileSystemRights -replace '\s')"}
... -Value (&$Val) ...