LOCATING FILES USING MULTIPLE STRING AND DATE CRITERIA - string

I am trying to use a code as follows, to locate files with specific strings, extension and lastwritetime :
get-childitem C:\users\nila9\Downloads -filter *.mkv -recurse
| where-object { $_.Name -match ("*bluray*" -and "*1080*") -and $_.lastwritetime -match "11/20/2020" }
The code is meant to first filter all files in the downloads folder with the extension *.mkv and then further shortlist for filenames containing the string "bluray" and "1080" and modified after the specified date.
While this code does not return any error, it does however not execute and releases the control to the prompt.
Is there someplace I am getting it wrong?
Thanks

As Lee_Dailey pointed out, -match uses regex and needs a different syntax. Your code needs a different operator that handles wildcards (*) and for that, there is -like
Also, you should not try to compare a DateTime object with a string, so -match is no good for that either.
If a filename needs BOTH bluray AND 1080, you can change the code to
$refDate = (Get-Date -Year 2020 -Month 11 -Day 20).Date # set time part to all 0 (--> midnight)
Get-ChildItem -Path 'C:\users\nila9\Downloads' -Filter '*.mkv' -Recurse |
Where-Object { $_.Name -like "*bluray*" -and $_.Name -like "*1080*" -and $_.LastWriteTime -ge $refDate }
If however the file needs to have bluray OR 1080 in its name, you can use -match on that part:
$refDate = (Get-Date -Year 2020 -Month 11 -Day 20).Date # set time part to all 0 (--> midnight)
Get-ChildItem -Path 'C:\users\nila9\Downloads' -Filter '*.mkv' -Recurse |
Where-Object { $_.Name -match "bluray|1080" -and $_.LastWriteTime -ge $refDate }
The pipe symbol | in regex is the OR operator

Related

Display Data on Two Columns Within Excel

I am trying to display data within an Excel document where Column A displays the server name and column B displays the .NET version. I'm running into an issue exporting to a .csv because it says that the file path does not exist. I would like some guidance on how I can resolve that issue and how I can display data on the two columns within Excel.
$Servers =
(
"test"
)
foreach ($Server in $Servers)
{
Invoke-Command -ComputerName $Server -ScriptBlock {
Write-Output "$(hostname)"
Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse | Get-ItemProperty -Name Version,Release -EA 0 | where { $_.PSChildName -match '^(?!S)\p{L}'} | select PSChildName, Version, Release | Select -ExpandProperty Version | Sort-Object Version | Export-Csv -Path C:\Users\User\Desktop\example.csv
}
The main issue is that you're using Export-Csv on the remote hosts since it is inside the Invoke-Command script block, and the likeable error is because the path you are using as export doesn't exist on those hosts.
It's also worth noting that Invoke-Command can run in parallel, -ComputerName as well as -Session can take an array, this removes the need for the foreach loop as well as it is much faster / efficient.
Invoke-Command -ComputerName $servers -ScriptBlock {
Write-Host "Working on $($env:COMPUTERNAME)..."
Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse |
Get-ItemProperty -Name Version, Release -EA 0 |
ForEach-Object {
if($_.PSChildName -notmatch '^(?!S)\p{L}') {
return # skip this
}
[pscustomobject]#{
HostName = $env:COMPUTERNAME
Version = $_.Version
}
} | Sort-Object Version
} -HideComputerName | Select-Object * -ExcludeProperty RunspaceID |
Export-Csv -Path C:\Users\User\Desktop\example.csv -NoTypeInformation

Searching contents of text files on remote computers and exporting to excel file using powershell and export-excel

I'm trying to search the contents of text files on remote computers from computers.txt which includes
Pc1
Pc2
Pc3
Pc4
And export it using export-excel PowerShell module
using this code:
$directory = $PSScriptRoot
$computers = Get-Content -Path $directory\computers.txt
$searchwords = 'word1','word2','word3'
Foreach ($computer in $computers) {
$path = "\\$computer\C$\test\logs"
Foreach ($sw in $searchwords) {
$excel = Get-Childitem -path $path -recurse -Include "*.txt" |
Select-string -pattern "$sw" |
Select-object pattern, linenumber, line, path |
Export-excel $file -autosize -startrow 1 -tablename pattern -worksheetname "errors" -passthru
$ws = $excel.workbook.worksheets['errors']
$excel.save()
}
}
The problem is that it will only export the contents of pc4 which is the last in the computers.txt list.
Thanks in advance
Adding the -append switch on export-excel will get this working.
It was added as part of the release on 10/30/2017 - https://github.com/dfinke/ImportExcel#whats-new-in-release-52

How can I copy a column value from excel to csv file without using ComObject

I'm new to Power shell. I have a number of excel files (500+) having a column Animal Count that I would like to save in a new '.csv' file. I have a code to do this using excel Com Objects.
I want to achieve the same without using ComObjects. Could anyone help me in achieving this.
Download PSExcel module from
https://github.com/RamblingCookieMonster/PSExcel
Import it using Import-Module.
then use the following code:
$AnimalCount = #()
$Source = 'D:\Test' # the path to where the Excel files are
ForEach ($File in Get-ChildItem -Path $Source -Filter '*.xlsx' -File) {
$Excel = New-Excel -Path $File
$Cell = ($Excel | Get-WorkSheet | % {$_.Cells | ? {$_.Text -eq "AnimalCount"}})
$count = (($Excel | Get-WorkSheet -Name $Cell.Worksheet).Cells | ? {($_.Start.Row -eq $Cell.Start.Row) -and ($_.Start.Column -eq $Cell.Start.Column + 1)}).Text
$AnimalCount += [PsCustomObject] #{'File' = $File.FullName; 'AnimalCount' = $count }
}
$AnimalCount | Format-Table -AutoSize
$AnimalCount | Export-Csv -Path 'D:\Test\AnimalCount.csv' -UseCulture -NoTypeInformation
The best thing here is that you do not need excel to be installed on the machine that runs this script.

Remove matching collection object from text file

I have a list of users that I am storing in a text file. I am trying to update the text file so it removes any user that match $NotExpiring users variable, which is a collection. I just can't figure out how I would update the text file properly if more than one user needs to be removed from text file.
Below is the full function. You can ignore most of it Just look under #Stuck Here to get to the point.
function Get-NotExpiring{
$NotExpiring=New-Object System.Collections.Generic.List[System.Object]
$MatchedUser=New-Object System.Collections.Generic.List[System.Object]
$textfiles = Get-ChildItem $email_dir
#Day of Span
$Days="20"
#Settings
$Date=Get-Date ((Get-Date).adddays($Days))
$Users=Get-ADUser -filter {(Enabled -eq $True) -and (PasswordNeverExpires -eq $False)} -Properties SamAccountName, DisplayName, msDS-UserPasswordExpiryTimeComputed, Mail | Where-Object { $_.DisplayName -ne $nul -and ($_."msDS-UserPasswordExpiryTimeComputed" -gt ($NotExpDate.ToFileTime()))} | Select SamAccountName, Mail, DisplayName,#{Name="ExpiryDate";Expression={([datetime]::fromfiletime($_."msDS-UserPasswordExpiryTimeComputed")).DateTime}}
#Magic
foreach ($Entry in $Users) {
$EntryDate = Get-date($Entry.ExpiryDate)
if ($EntryDate -gt $Date){
$Account = $Entry.SamAccountName
$ExpDate = $Entry.ExpiryDate
$NotExpiring.add($Account)
}
}
#STUCK HERE
foreach($file in $textfiles){
foreach ($user in $NotExpiring){
if((Get-Content "$email_dir\$file") -contains $user){
$temp_get = Get-Content $email_dir\$file | where {$_ -notmatch $user}
}}}
$temp_get}
I tried below but it doesn't seem to work if more than one user are $NotExpiring that are also in the existing textfile. Any help would be appreciated. I know this is a simple fix but I can't seem to figure it out.
Get-Content $email_dir\$file | where {$_ -notmatch $user} | Set-Content <path>.txt
I was able to achieve exactly what I needed using the following solution.
foreach($file in $textfiles){ foreach ($user in $NotExpiring){
if((Get-Content "$email_dir\$file") -contains $user){
$MatchedUser.add($user)
}}
Get-Content "$email_dir\$file" | Where {$MatchedUser -NotContains $_ } | Set Content "$temp_dir\$file"
Copy-Item -path "$temp_dir\$file" -Destination "$email_dir\$file" -ErrorAction SilentlyContinue }
Basicly you are trying to match two arrays.
With where you do it foreach object. Now you have to match the single object $_ with the array $user.
Use:
...| where {$_ -notin $user}
or
...| where {$user -notcontains $_}

Renaming many folders in PowerShell

I have over 1000+ files that have to be renamed.
The first set folder and/or files are grouped by location, so the first four characters are the same for each file; there are four-five different locations. I need to delete the first few characters of the folder's name.
Example:
Old File: ABC_Doe, Jane
New File: Doe, Jane
any suggestions as to the quickest way to carry this out?
I've tried all of the following:
1st Attempt
$a = Get-ChildItem C:\example
$b = Where-Object {$_.name -like “*ABC_*”}
$cmdlet_name = “Rename-Item”
$d = (cmdlet_name $a $b)
invoke-expression $d
2nd Attempt
$e = Get-ChildItem C:\example
$f = $e.TrimStart (“ABC_”)
3rd Attempt
Rename-Item -{$_.name -like “*ASD*”, “”}
Try this, get all child items (files only), remove abc_ by replacing them (with nothing) and rename each file. To rename files in sub-directories add the -Recurse switch to the Get-ChildItem command:
Get-ChildItem c:\example -Filter ABC_* | Where-Object {!$_.PSIsContainer} | Rename-Item -NewName { ($_.BaseName -replace '^ABC_') + $_.Extension }
UPDATE
Actually, this should work as well and is much shorter (no need to append the file extension cause renaming is performed on the file name).
Get-ChildItem c:\example -Filter ABC_* | Where-Object {!$_.PSIsContainer} | Rename-Item -NewName { $_.Name -replace '^ABC_' }
get-childItem ABC_* | rename-item -newname { $_.name -replace 'ABC_','' }
Source: get-help rename-item -full

Resources