Im trying to find every drive letter that isnt "C,E,L,S,T,W" on a windows 2008 server. Can anyone tell me the fault in my logic or how i can do this please?
[char[]]”CELSTW” | Where-Object {!(Get-PSDrive $_ )}
You are starting out with a list of drive letters you don't want (CELSTW) and outputting the ones that don't exist as a psdrive.
What you want is to start with a list of all PSDrives and filter them out where they match the ones you don't want:
Get-PSDrive | Where-Object { [char[]]"CELSTW" -notcontains $_.Name }
Although that is going to give you a bunch of other PSDrive types. You probably also want to filter it for the FileSystem provider:
Get-PSDrive | Where-Object { [char[]]"CELSTW" -notcontains $_.Name -AND $_.Provider.Name -eq "FileSystem"}
This should give you all psdrives where the name (driveletter) isn't "C,E,L,S,T,W"
Get-PSDrive | ?{[char[]]"CELSTW" -notcontains $_.name}
however if you want to exclude non-filesystem psdrives, try this:
Get-PSDrive | ?{[char[]]"CELSTW" -notcontains $_.name} | ?{$_.Provider.name -eq "FileSystem"}
You must go for this from the other end:
$drives = [char[]]"CD"
Get-PSDrive | ? { $drives -notcontains $_.Name}
Another example using the -notmatch operator:
Get-PSDrive | Where-Object { $_.Name -notmatch '[CELSTW]'}
Related
I'm trying to exclude two drives from a file search. I'm getting an error when running the code: "Get-ChildItem : Access to the path 'C:\Windows\system32\LogFiles...'". The search shouldn't touch C. Help!! What am I doing wrong? Code attached.
$Drives = Get-PSDrive -PSProvider FileSystem | where { -not ('c','u' -eq $_.name) }
$FS='(.*18)\.FOO'
$FPath=#(foreach($Drive in $drives) {
Get-ChildItem -Path $Drive.Root -Recurse | Where-Object {$_.Name -match $FS} -ErrorAction SilentlyContinue | %{$_.Name}
})
I think you are looking for
Get-PSDrive -PSProvider FileSystem |
Where-Object {"c","u" -notcontains $_.name} |
ForEach-Object{
Get-ChildItem -Path $_.Root -Recurse |
Where-Object {$_.Name -match '(.*18)\.FOO'} -ErrorAction SilentlyContinue |
select Name
}
Seems based on your comments you are still getting the error. Lets trouble shoot it a bit. Lets output the drive that it really seems to error on.
Get-PSDrive -PSProvider FileSystem |
Where-Object {"c","u" -notcontains $_.name} |
ForEach-Object{
$Drive = $_.Name
try{
Get-ChildItem -Path $_.Root -Recurse |
Where-Object {$_.Name -match '(.*18)\.FOO'} -ErrorAction SilentlyContinue |
Select Name
}catch{
#{
Drive = $Drive
}
}
}
How do I properly use $_ in out-file? Here's my code:
get-content computers.txt |
Where {$_ -AND (Test-Connection $_ -Quiet)} |
foreach { Get-Hotfix -computername $_ } |
Select CSName,Description,HotFixID,InstalledBy,InstalledOn |
convertto-csv | out-file "C:\$_.csv"
I'm trying to execute a get-hotfix for all the computers listed in the text file then I want them to be exported to CSV with the computer name as the filename.
You need one pipeline to process the computers.txt files, and a nested one inside the foreach to process the list of hotfixes for each computer:
get-content .\computers.txt |
Where {$_ -AND (Test-Connection $_ -Quiet)} |
foreach {
Get-Hotfix -computername $_ |
Select CSName,Description,HotFixID,InstalledBy,InstalledOn |
convertto-csv | out-file "C:\$_.csv"
}
Edit: Changed computers.txt to .\computers.txt, as this is required for local paths in powershell
i can see with this:
get-content .\computers.txt | Where {$_ -AND (Test-Connection $_ -Quiet)} | foreach{ Get-Hotfix -id KB4012212 -computername $_ | Select CSName,Description,HotFixID,InstalledBy,InstalledOn | convertto-csv | out-file "C:\$_.csv" }
i can see only in which PC is the fix (KB4012212) installed.
it's possible to see the following
CSNAME Fix(Inst/NotInst)
PC1 FIxInstalled
PC2 FixNotinstalled
PC3 FixnotInstalled
..
..
etc
I monkeyed with this for a while and nothing I found on-line worked until I used this combo.
I used the method is this thread but it was SO slow and I wanted to learn more about using jobs so this is what ended up working for me on Windows 7 PS Ver 4.
All other options were either too slow or did not return data from the remote system.
$VMs = get-content C:\WinVms.txt #Generate your hostnames list however you deem best.
foreach ($vm in $vms)
{
Write-Host "Attempting to get hotfixes on:" $vm
invoke-command -computername $vm -ScriptBlock {start-job -scriptblock {(get-hotfix | sort installedon)[-1]} | wait-job | receive-job} -AsJob
}
start-sleep 60 # give it a minute to complete
get-job | ? { $_.state -eq "Completed"} | receive-job -keep | export-csv c:\temp\win-patch.csv
you can check your failures too like this:
get-job | ? { $_.state -eq "Failed"}
I'm setting up a contacts file in .csv format, as downloaded from google, to read with powershell on my windows 10 laptop. I have a long way to go to make this practical, but the first thing I've tried, and almost succeeded in, is to write a script that prompts the user to enter a name and then responds with the phone number for them. That script looks like this:
Param(
[Parameter(Mandatory=$true, Position=0, HelpMessage="What's their name?")]
$TheirNameIs
)
Import-Csv "*MYPATH*.csv" |
Sort 'Family name' -descending |
Where-object {$_.Name -eq $TheirNameIs} |
Select-Object -Property 'Name','Phone 1 - Type','Phone 1 - Value'
The problem I am having is Where-object works with -eq to find exact matches to the name the user enters, but I wanted to use -contains so that I could type in a first name and get all the contacts with that value in their name. I tried replacing -eq with -contains but wasn't getting any output unless I used the exact contact name
Where am I going wrong with the Where-object cmdlet?
You could replace the -eq operator by the -like operator and insert wildcards:
Param(
[Parameter(Mandatory=$true, Position=0, HelpMessage="What's their name?")]
$TheirNameIs
)
Import-Csv "*MYPATH*.csv" |
Sort 'Family name' -descending |
Where-object {$_.Name -like "*$TheirNameIs*"} |
Select-Object -Property 'Name','Phone 1 - Type','Phone 1 - Value'
You could also go for regular expressions and use the -match operator like #Olaf already mentioned. A solution could look like this:
Param(
[Parameter(Mandatory=$true, Position=0, HelpMessage="What's their name?")]
$TheirNameIs
)
Import-Csv "*MYPATH*.csv" |
Sort 'Family name' -descending |
Where-object {$_.Name -match ".*$TheirNameIs.*"} |
Select-Object -Property 'Name','Phone 1 - Type','Phone 1 - Value'
I want to search all drives using PowerShell on windows machine to get the list of all files along with their extensions -
Based on desired extension we pass in it like - *.mp3 or
Fetch all files with multiple extensions like - *.txt, *.mp3 etc.
I tried below script but its giving only information from where we are running it. But I want to scan whole machine.
Get-ChildItem -Path .\ -Filter ***.doc** -Recurse -File| Sort-Object Length -Descending | ForEach-Object { $_.BaseName }
Checkout the Get-PSDrive cmdlet. It returns a list of drives, and you can specify just disk drives with the -PSProvider FileSystem parameter:
foreach ( $drive in $(Get-PSDrive -PSProvider FileSystem) ) {
Get-ChildItem -Path $drive.Root -Filter ***.doc** -Recurse -File |
Sort-Object Length -Descending |
ForEach-Object { $_.BaseName }
}
Didn't test that but you get the idea.
Using -Include on Get-ChildItem will allow you to specify a list of extensions. The -ErrorAction will cause it to skip drives that are not available such as an unmounted CD drive.
Get-PSDrive -PSProvider FileSystem |
ForEach-Object {
Get-ChildItem -Path $_.Root -Recurse -Include '*.doc*', '*.txt' -ErrorAction SilentlyContinue |
ForEach-Object { $_.Name }
} |
ForEach-Object {[PSCustomObject]#{HashCode = $_.GetHashCode(); FullName = $_.FullName}}
} |
Export-Csv -Path $TempFile -NoTypeInformation -Encoding ASCII
Update:
Here is a better way. It will prevent unknown extensions from getting into the mix such as "Microsoft.NET.Sdk.Publish.Docker.targets."
$ExtensionList = #('.txt', '.doc', '.docx', '.mp3')
$TempFile = Join-Path -path $Env:TEMP -ChildPath "$($pid.ToString()).tmp"
Get-PSDrive -PSProvider FileSystem |
ForEach-Object {
Get-ChildItem -Path $_.Root -Recurse -ErrorAction SilentlyContinue |
Where-Object { $ExtensionList -contains $_.Extension } |
ForEach-Object {
[PSCustomObject]#{
HashCode = $_.GetHashCode();
DirectoryName = $_.DirectoryName
Name = $_.Name
}
}
} |
Export-Csv -Path $TempFile -Delimiter ';' -NoTypeInformation -Encoding ASCII
Write-Host "The temp file is $TempFile"
This is more than what the original question asked, but if you are going to go through the trouble of listing all your files, I suggest getting the filehash as well so you can determine if you have duplicates. A simple file name search will not detect if the same file has been saved with a different name. Adding to what #lit (https://stackoverflow.com/users/447901/lit) has posted:
$ExtensionList = #('.txt', '.doc', '.docx', '.mp3')
Get-PSDrive -PSProvider FileSystem |
ForEach-Object {
Get-ChildItem -Path $_.Root -Recurse -ErrorAction SilentlyContinue |
Where-Object { $ExtensionList -eq $_.Extension } |
## ForEach-Object { $_.Name, $_.FullName, $_.GetHashCode() }
Select-Object #{Name="Name";Expression={$_.Name}}, #{Name="Hash";Expression={$_.GetHashCode()}}, #{Name="FullName";Expression={$_.FullName}} |
Export-Csv -Path C:\Temp\testing.csv -NoTypeInformation -Append
}
The addition of the file hash will allow you to see if you have duplicates and the full name will allow you to see where they are located.
Does anybody know a powershell 2.0 command/script to count all folders and subfolders (recursive; no files) in a specific folder ( e.g. the number of all subfolders in C:\folder1\folder2)?
In addition I also need also the number of all "leaf"-folders. in other words, I only want to count folders, which don't have subolders.
In PowerShell 3.0 you can use the Directory switch:
(Get-ChildItem -Path <path> -Directory -Recurse -Force).Count
You can use get-childitem -recurse to get all the files and folders in the current folder.
Pipe that into Where-Object to filter it to only those files that are containers.
$files = get-childitem -Path c:\temp -recurse
$folders = $files | where-object { $_.PSIsContainer }
Write-Host $folders.Count
As a one-liner:
(get-childitem -Path c:\temp -recurse | where-object { $_.PSIsContainer }).Count
To answer the second part of your question, of getting the leaf folder count, just modify the where object clause to add a non-recursive search of each directory, getting only those that return a count of 0:
(dir -rec | where-object{$_.PSIsContainer -and ((dir $_.fullname | where-object{$_.PSIsContainer}).count -eq 0)}).Count
it looks a little cleaner if you can use powershell 3.0:
(dir -rec -directory | where-object{(dir $_.fullname -directory).count -eq 0}).count
Another option:
(ls -force -rec | measure -inp {$_.psiscontainer} -Sum).sum
This is a pretty good starting point:
(gci -force -recurse | where-object { $_.PSIsContainer }).Count
However, I suspect that this will include .zip files in the count. I'll test that and try to post an update...
EDIT: Have confirmed that zip files are not counted as containers. The above should be fine!
Get the path child items with recourse option, pipe it to filter only containers, pipe again to measure item count
((get-childitem -Path $the_path -recurse | where-object { $_.PSIsContainer }) | measure).Count