Capture Get-ChildItem results into string array for HTML output - string

I'm writing a PowerShell script and I want to capture the list of files in a directory and store into a variable. Once captured I'd like to print it to an HTML file. I've captured the data like this:
$listDownloads = Get-ChildItem -Force "C:\Users\Someuser\Downloads"
Now, I want to convert $listDownloads into a string and split it. How do I go about doing that?
I've tried this:
$listSplit = $listDownloads.ToString().Split(" ")
but I get this output:
System.Object[]
Updated:
$html = '<html>'
$body = '<body>'
$p = '<p>'
$pClose = '</p>'
$StatusDownloads = 'Directory of the Downloads Folder'
$pTags = $p.ToString() + $StatusDownloads + $pClose.ToString();
$listDownloads = (Get-ChildItem -Force "C:\Users\Someuser\Downloads").Name;
function createHTML($addtoFile){
$addtoFile | Add-Content 'status.html'
}
function printData($printData){
Write-Output $printData
}
$html | Set-Content 'status.html'
createHTML($html)
createHTML($body)
createHTML($pTags)
createHTML($listDownloads)
When I try to print $listDownloads it gives me the data all on the same line (i.e. File 1 File 2) I want each file or folder displayed on a new line. How would I do that? If I were to type Get-ChildItem -Force "C:\Users\Someuser\Downloads" into Powershell it would give the list of files line by line. I want that type of output on my HTML page.

The only reason I can think you want to split is to get an array of filenames.
If that's the case, you can do:
$list = (Get-ChildItem -Force "C:\Users\Someuser\Downloads").FullName
From your update you would need to pass into your function as:
createHTML($listDownloads -join "`n")

Related

How can I modify this PowerShell script to continue looking for one string after another?

I want this power shell script to search for the occurrence of multiple strings, one after the other, and to append the results in a .txt file.
Currently I am specifying the string that I want to look for, waiting for the script to finish looking for that string and transferring the results into a spreadsheet. This is taking a lot of time as I have to keep specifying the string I want to look for, especially since there are well over 100 that I need to look for.
#ERROR REPORTING ALL
Set-StrictMode -Version latest
$path = "C:\Users\username\Documents\FileName"
$files = Get-Childitem $path -Include *.docx,*.doc,*.ppt, *.xls,
*.xlsx, *.pptx, *.eap -Recurse | Where-Object { !($_.psiscontainer) }
$output =
"C:\Users\username\Documents\FileName\wordfiletry.txt"
$application = New-Object -comobject word.application
$application.visible = $False
$findtext = "First_String"
Function getStringMatch
{
# Loop through all *.doc files in the $path directory
Foreach ($file In $files)
{
$document = $application.documents.open($file.FullName,$false,$true)
$range = $document.content
$wordFound = $range.find.execute($findText)
if($wordFound)
{
"$file.fullname has found the string called $findText and it is
$wordfound" | Out-File $output -Append
}
}
$document.close()
$application.quit()
}
getStringMatch
This script will look for 'First_String' successfully, I was hoping to be able to specify 'Second_String', 'Third_String' etc rather than replace First_String every time.
As an alternative to the suggestion from #Mathias, you could use Regex to query the document text instead.
Read the context of the document as a string $text = $document.content.text and then use Select-String $findtext -AllMatches to evaluate the matches with $findtext as string representation of a regular expression instead.
Example:
# pipe delimited string as a regular expression
$findtext = "First_String|Second_String|Third_String"
Function getStringMatch
{
# Loop through all *.doc files in the $path directory
Foreach ($file In $files)
{
$document = $application.documents.open($file.FullName,$false,$true)
$text = $document.content.text
$result = $text | Select-String $findtext -AllMatches
if($result)
{
"$file.fullname has found the strings called $($result.Matches.Value) at indexes $($result.Matches.Index)" | Out-File $output -Append
}
}
$document.close()
$application.quit()
}
Note that if you're trying find strings that do have reserved regex character, you'll need to escape them first

powershell export variable to txt file

I need to extract a variable on a single line in a txt file like so;
Write-Host "Select RDS Collection to migrate"
$AllCollections.Keys | Sort-Object | ForEach-Object { Write-Verbose "[$_] - $($AllCollections.$_)" -Verbose }
Write-Output ''
$Collection = $AllCollections.$((Read-Host -Prompt 'Choose collection number') -as [int])
$oldrdscb = "RDSCB01N01"
$newrdscb = "RDSCB02N01"
$newrdscbsmb = "\\$newrdscb\C$\temp\migrationvariables.txt"
echo "$collection" = "$Collection" | Out-File -FilePath $newrdscbsmb -append -width 200
txt file \RDSCB02N01\c$\temp\migrationvariables.txt now containts:
RDS-FSLOGIXTEST
=
RDS-FSLOGIXTEST
this because it reads the first $collection and the gives the output of $collection variable, which makes sense.
How can i get the result without the variable of the first $collection and send it as text instead of a variable so the end result in the txt would be:
$collection = TEST
The txt is emtpy before running this code.
The Goal here is to read the variables on my new rds server to migrate theme.
Any tips? thank you!
You just need to escape the dollar signs using the backtick (`). It is usually above the tab key on the keyboard.
$oldrdscb = "RDSCB01N01"
$newrdscb = "RDSCB02N01"
$newrdscbsmb = "\\$newrdscb\C$\temp\migrationvariables.txt"
echo "`$collectioname" = "`$Collection" | Out-File -FilePath $newrdscbsmb -append -width 200

Powershell comparing data in a CSV against files in a folder

I'm fairly new to powershell.
I'm trying to compare data in a CSV File against random files in a specific folder.
I want to see if and what has changed and then log that in another column called "Changed".
Here's what I've done below, it seems to create a new column called 'Changed' but doesn't input the changes in it.
$Spreadsheet = 'C:\Powershell\CSV\inv.csv'
$SpreadSheetPath = "C:\Powershell\CSV"
Import-Csv $Spreadsheet -Delimiter "|" -Encoding Default | ForEach-Object -
{
$Path += $_.Path
$Filename += $_.Filename
$DateModified += $_.DateModified
$FileSize += $_.FileSize
$MD5Hash += $_.MD5Hash
}
{
$Msg1 = "Path changed"
$Msg2 = "File Name changed"
$Msg3 = "Date Modified changed"
$Msg4 = "File Size changed"
$Msg5 = "MD5 changed"
$Msg6 = "Files are the same"
$psdata = "D:\ps-test\data\*.*"
}
If (($Path -eq $psdata))
{
Import-Csv C:\Powershell\CSV\inv.csv |
Select-Object *,#{Name='Changed';Expression={$Msg6}} |
Export-Csv C:\Powershell\CSV\NewSpreadsheet4.csv
}
Else
{
Import-Csv C:\Powershell\CSV\inv.csv |
Select-Object *,#{Name='Changed';Expression={$Msg1}} |
Export-Csv C:\Powershell\CSV\NewSpreadsheet4.csv
}
Here is an example of what the CSV looks like:
Path Filename Date Modified File Size MD5 Hash
D:\ps-test\data adminmodeinfo.htm 03/11/2010 22:42 1079 BD1C9468D71FD33BB35716630C4EC6AC
E:\ps-test\data admintoolinfo.htm 03/11/2010 22:42 868 24B99B6316F0C49C23F27FEA6FF1C6AC
E:\ps-test\data admin_ban.bmp 03/11/2010 22:42 63480 C856F1F3C58962B456E749F2EA9C933A
E:\ps-test\data baseline.dat 03/20/2010 03:18:33 173818 F13183D88AABD1A725437802F8551A06
E:\ps-test\data blueRule.gif 03/11/2010 22:42 815 D1AEFE884935095DAB42DAFD072AA46F
E:\ps-test\data deffactory.dat 03/20/2010 03:18:33 706 862D4DFD2F49021BB7C145BDAFE62F6F
E:\ps-test\data dividerArt.jpg 03/11/2010 22:42 367 F7050C596C097C0B01A443058CD15E35
There are many issues with your code.I will try to highlight a few of the issues, link to documentation and point you in the right direction so that you can resolve your issues. A proper solution would require getting many more requirements, or writing code (off-topic for StackOverflow)
Change
| ForEach-Object -
{
to
| ForEach-Object {
In the Foreach-Object, you are concatenating values from each line because you are using +=.
On the first run, $Path contains D:\ps-test\data.
After the second run, it contains D:\ps-test\dataE:\ps-test\data.
At the end of your test data, it contains D:\ps-test\dataE:\ps-test\dataE:\ps-test\dataE:\ps-test\dataE:\ps-test\dataE:\ps-test\dataE:\ps-test\data
The messages are contained in a script block, but it does not look like this is intentional as this is never executed. So after the scriptblock, the variable $Msg1 has not been created; it's blank.
If (($Path -eq $psdata))
double brackets not required.
will always be false because the variable $psdata does not exist as it was stated inside a script block.
will always be false because you are attempting to equate the strings; your input does not literally contain "D:\ps-test\data\*.*". You probably want -like instead of -eq.
will always be inaccurate because even if the paths are compared, there is no check that the file actually exists on the system.
Useful links
Test-Path to check if file exists.
Get-FileHash to get MD5 hash and compare to file.
Get-ChildItem to get a list of directories/files in a directory.
Write-Output so that you can print variables and make sure they contain what you expect.
about_comparison_operators - -in and -contains will help you.
This is a suggestion to help you get started. It's not complete and not tested! Let me know if it works as expected and if you have any questions.
Import-Csv 'C:\Powershell\CSV\inv.csv' -Delimiter "|" -Encoding Default | foreach {
$Path += $_.Path
$Filename += $_.Filename
$DateModified += $_.DateModified
$FileSize += $_.FileSize
$MD5Hash += $_.MD5Hash
$file = [System.IO.FileInfo](Join-Path $Path $Filename)
if (-not $file.Exists) {
$message = "File does not exist"
}
elseif ($file.LastWriteTime -ne [DateTime]$DateModified) {
$message = "Dates differ"
}
elseif ($file.Length -ne [int]$FileSize) {
$message = "Sizes differ"
}
# and so on...
# (You cannot really compared a changed file name btw)
New-Object -Type PSObject -Prop #{
Path = $Path
Filename = $Filename
DateModified = $DateModified
FileSize = $FileSize
MD5Hash = $MD5Hash
Message = $message
}
} | Export-CSV 'C:\Powershell\CSV\NewSpreadsheet4.csv'

Powershell - Pulling string from txt, splitting it, then concatenating it for archive

I have an application where I am getting a list of new\modified files from git status, then I take the incomplete strings from that file, concatenate them with the root dir file path, then move those files to an archive. I have it half working, but the nature of how I am using powershell does not provide error reports and the process is obviously erroring out. Here is the code I am trying to use. (It has gone through several iterations, please excuse the commented out portions) Basically I am trying to Get-Content from the txt file, then replace ? with \ (for some reason the process that creates the txt love forward slashes...), then split that string at the spaces. The only part of the string I am interested in is the last part, which I am trying to concatenate with the known working root directory, then I am attempting to move those to an archive location. Before you ask, this is something we are not willing to track in git, due to the nature of the files (they are test outputs that are time stamped, we want to save them on a per test run basis, not in git) I am still fairly new to powershell and have been banging my head against this rock for far too long.
Get-Content $outfile | Foreach-Object
{
#$_.Replace("/","\")
#$lineSplit = $_.Split(' ')
$_.Split(" ")
$filePath = "$repo_dir\$_[-1]"
$filePath.Replace('/','\')
"File Path Created: $filePath"
$untrackedLegacyTestFiles += $filePath
}
Get-Content $untrackedLegacyTestFiles | Foreach-Object
{
Copy-Item $_ $target_root -force
"Copying File: $_ to $target_root"
}
}
the $outfile is a text file where each line has a partial file path leading to a txt file generated by a test application we use. This info is provided by git, so it looks like this in the $outfile txt file:
!! Some/File/Path/Doc.txt
The "!!" mean git sees it as a new file, however it could be several characters from a " M" to "??". Which is why I am trying to split it on the spaces and take only the last element.
My desired output would be to take the the last element of the split string from the $outfile (Some/File/Path/Doc.txt) and concatenate it with the $repo_dir to form a complete file path, then move the Doc.txt to an archive location ($target_root).
To combine a path in PowerShell, you should use the Join-Path cmdlet. To extract the path from your string, you can use a regex:
$extractedPath = [regex]::Match('!! Some/File/Path/Doc.txt', '.*\s(.+)$').Groups[1].Value
$filePath = Join-Path $repo_dir $extractedPath
The Join-Path cmldet will also convert all forward slashes to backslashes so no need to replace them :-).
Your whole script could look like this:
Get-Content $outfile | Foreach-Object {
$path = Join-Path $repo_dir ([regex]::Match($_, '.*\s(.+)$').Groups[1].Value)
Copy-Item $path $target_root -force
}
If you don't like to use regexin your code, you can also extract the path using:
$extractedPath = '!! Some/File/Path/Doc.txt' -split ' ' | select -Last 1
or
$extractedPath = ('!! Some/File/Path/Doc.txt' -split ' ')[-1]

PowerShell Get ACL For Folders In A Text File

I have a text file with the exact paths of the folders that I want to get permission information from, and I am trying to use PowerShell to get the information from each folder. I want to add the information to a text file, with a delimiter value of ":"
Can someone please tell me what I am doing wrong...
$FullList = Get-Content "C:\Temp\ListofFoldersToCheck.txt"
$DataOutFile = "C:\Temp\PermissionInformation.txt"
Foreach ($Folder in $FullList)
{
$ACLs = get-acl $Folder.Fullname | ForEach-Object { $_.Access }
Foreach ($ACL in $ACLs)
{
$DataOutInfo = $Folder.FullName + ":" + $ACL.IdentityReference
Add-Content -Value $DataOutInfo -Path $DataOutFile
}
}
It is returning the error message: Get-Acl: Cannot validate argument on parameter 'Path'. The argument is null or empty. Provide an argument that is not null or empty, and then try
the command again.
The $FullList data is separated by new lines, if that makes any difference.
Please help, this is driving me insane...
Hey The Woo you miss something here :
$Folder is a string, not a FileInfo (you should use Get-Item for that), so you should begin by : get-acl $Folder and not get-acl $Folder.Fullname.
Then you should just write :
$ACLs = (get-acl $Folder).Access

Resources