Powershell get-childitem against remote server - powershell

I would like to get size of user profiles across all servers in OU remotely, I tried this script, but without success
$Exclude = #('admsupp','all users','public','Default','Default user')
$servers = Get-ADComputer -SearchBase "OU=Horizon8,OU=xxx,OU=x,OU=xxx,DC=xx,DC=xx" -Filter *
foreach ($server in $servers)
{
gci -force -path \\$server.dnshostname\c$\users -Exclude $Exclude -ErrorAction SilentlyContinue | ? { $_ -is [io.directoryinfo] } | % {
$len = 0
gci -recurse -force $_.fullname -ErrorAction SilentlyContinue | % { $len += $_.length }
$_.fullname, '{0:N2} GB' -f ($len / 1Gb)
}
}
can someone advise please how to achieve this?
Thank you

The path you construct is wrong.
The way you write \\$server.dnshostname\c$\users will not give you what you think and you should either use a sub expression inside a double-quoted string:
Get-ChildItem -Path "\\$($server.DNSHostName)\c$\users"
or construct it using the -f Format operator like:
Get-ChildItem -Path ('\\{0}\c$\users' -f $server.DNSHostName)
Then, because you don't want to use recursion in the first Get-ChildItem, the -Exclude parameter does not function and instead use the -Directory switch and a Where-Object clause after that to exclude the folders you do not want:
Get-ChildItem -Path "\\$($server.DNSHostName)\c$\users" -Directory | Where-Object { $Exclude -notcontains $_.Name }
As per your comment, if you have server names all starting with a single letter followed by one or more digits and you want to construct a longer path using that, you could do
# construct the path:
# if computername is 'V10testcomputer', this will result in'\\V10testcomputer\c$\Users\testcomputer\AppData'
$path = '\\{0}\c$\users\{1}\AppData' -f $server.DNSHostName, ($server.DNSHostName -replace '^[A-Z]\d+(.*)', '$1')
Get-ChildItem -Path $path -Directory | Where-Object { $Exclude -notcontains $_.Name }

Your problem is the way you construct the Path, see #Theo's answer.
But you can do it far more quickly with Measure-Object instead of another For-Each loop.
You don't have to test the DirectoryInfo type, unless you are still using PowerShell 2, simply use the -Directory parameter.
$Exclude = #('admsupp','all users','public','Default','Default user')
$servers = Get-ADComputer -SearchBase "OU=Horizon8,OU=xxx,OU=x,OU=xxx,DC=xx,DC=xx" `
-Filter *
foreach ($server in $servers)
{
gci -Force -Path "\\$($server.dnshostname)\c$\users" -Exclude $Exclude `
-Directory -ErrorAction SilentlyContinue |
% {
$_.Fullname, '{0:N2} GB' -f ((gci -Recurse -Force $_.Fullname `
-ErrorAction SilentlyContinue | Measure-Object `
-Property Length -Sum).Sum / 1Gb)
}
}
I Suggest you to prefer this
$_.Fullname, (gci -Recurse -Force $_.Fullname -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum).Sum
because reusing this info is easier than text data

#theo
Hi,
currently I am running this script
$Exclude = #('admsupp','all users','public','Default','Default user')
$servers = Get-ADComputer -SearchBase "OU=xxx,OU=xxx,OU=xxx,DC=xxx,DC=xxx" -Filter *
$path = '\\{0}\c$\users\{1}\AppData\roaming' -f $server.name, ($server.name -replace '^[A-Z]\d+(.*)', '$1')
foreach ($server in $servers) {
$colItems = Get-ChildItem -Path $path -Exclude $Exclude | Where-Object {$_.PSIsContainer -eq $true} | Sort-Object
foreach ($i in $colItems)
{
$subFolderItems = Get-ChildItem $i.FullName -recurse -force | Where-Object {$_.PSIsContainer -eq $false} | Measure-Object -property Length -sum | Select-Object Sum
$i.FullName + ”;” + “{0:N2}” -f ($subFolderItems.sum / 1GB) + ” GB” >> C:\users\xxx\export.txt
$i.FullName + ”;” + “{0:N2}” -f ($subFolderItems.sum / 1GB) + ” GB”
}
}
excludes are working fine like this, but the script failes immediately after start without any error message. Only thing that I have changed is the path regarding your advice:$path = '\\{0}\c$\users\{1}\AppData\roaming' -f $server.name, ($server.name -replace '^[A-Z]\d+(.*)', '$1')

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})

I am trying to get the files in zip format which were newly created around two days ago using powershell and I am not getting any output

$Servers = Get-content 'D:\utils\Backup\SBX servers.txt'
foreach($Path in $Servers){
$Path = "E:\Backup"
$result = Get-ChildItem E:\Backup\*_DB.zip -Recurse -Force -File |Format-Wide| Where-Object { $_.LastWriteTime -gt (get-date).AddDays(-1)}
$result
}
you were not far from the solution, but there are multiple problem with your syntax. First you should not "filter" (where-object), after "formating" (Format-wide).
foreach($Path in $Servers){
$Path = "E:\Backup"
$result = Get-ChildItem E:\Backup*DB.zip -Recurse -Force -File | Where-Object { $_.LastWriteTime -gt (get-date).AddDays(-1)}
$result | Format-Wide
}
you were missing the "underscore" in your filter too: "$." -> "$_."

nothing returned to variable when assigning to recursive gci search omitting folders using powershell v2

I am trying to recursively search for files on a windows 7 machine + network drives attached to it while excluding certain folders i.e. C:\windows & all recursive folders in this such as system32.
I know this question has been asked before but following the answers has not helped and I am still left with a blank variable.
Here are the combinations I have tried:
$AllDrives = Get-PSDrive
$files=#("*.xml",*.txt)
foreach ($Drive in $AllDrives) {
if ($Drive.Provider.Name -eq "FileSystem") {
$filenames = Get-ChildItem -recurse $drive.root -include ($files) -File | Where-Object {$_.PSParentPath -notlike "*Windows*" -and $_.PSParentPath -notlike "*Microsoft*"
}
}
I have also tried these combinations:
$filenames = Get-ChildItem -recurse $drive.root -include ($files) -File | Where-Object {$_.PSParentPath -notmatch "Program Files|Users|Windows"}
$exclude_pattern = $drive.root + "Windows"
$filenames = Get-ChildItem -Force -Recurse -path $drive.root -Include $files -Attributes !Directory+!System -ErrorAction "SilentlyContinue" | Where-Object { $_.PSIsContainer -eq $false } | Where-Object { $_.FullName -notmatch $exclude_pattern }
Unfortunately, after an amount of time has elapsed, when I type $filename into the terminal nothing has been assigned to it.

User Profile Names and Sizes into CSV File

This script gets user profiles on a machine and I am able to provide the output into a text file but I cannot figure out how to export this information to a CSV file.
dir C:\Users | foreach -Begin {} -Process {
$size = (dir $_.FullName -Recurse -Force -EA SilentlyContinue | Measure-Object ‘length’ -Sum -Maximum).Sum
Write-Output ("{0:n2}" -f ($size/1MB) + " MB", $_.FullName) >> "C:\scripts\UserProfiles\UserProfiles.txt"
}
You'll need to create an object with properties and then use Export-Csv
Get-ChildItem C:\Users |
ForEach-Object `
-Begin { Write-Host -Object "Scanning user directories" } `
-Process {
Write-Host "Scanning path '$($_.FullName)'"
$Size = (Get-ChildItem $_.FullName -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object ‘length’ -Sum -Maximum).Sum
[pscustomobject] #{
Name = $_.Name
Path = $_.FullName
Size = '{0:N2} MB' -f ( $Size / 1MB )
}
} |
Export-Csv -Path C:\Scripts\UserProfiles\UserProfiles.csv -NoTypeInformation

Count doesn't applied to -include jpg

I have following script:
$Extension = "*.jpg"
Get-ChildItem -Path 'C:\Users\DAVID\Documents\Test' -Directory | ForEach-Object {
$FilesInFolder = #($_ | Get-ChildItem -Recurse -Include $Extension -File -Force)
$FileSize = $FilesInFolder | Measure-Object -Property Length -Sum |
Select -ExpandProperty Sum
$FileSize = "{0:N2}" -f ($FileSize/1MB) + " MB"
$NumFiles = $FilesInFolder.Count
}
But it always counts everything in folder includes .zip files and .exe.
What am I doing wrong here? How can I get it to count only .jpg files. Can't find any solution but I'm thinking that it has something with this line to do:
$FilesInFolder = #($_ | Get-ChildItem -Recurse -Include $Extension -File -Force)
I can't fully explain this, because the docs are a little unclear on this issue but your suspicion is right. You have at least two simple ways to get the correct result:
Use -Filter instead of -Include
$FilesInFolder = #($_ | Get-ChildItem -Recurse -Filter $Extension -File -Force)
Explicitly specify the path instead of using the input object
$FilesInFolder = #(Get-ChildItem -Path $_.FullName -Recurse -Include $Extension -File -Force)
Especially the second version makes me think that this is maybe a bug (or at least very strange behaviour) in Get-ChildItem
I think the problem is $_ | Get-ChildItem is not resulting in the Path of the objects being piped to the Path property (because $_ instead has a property named PSPath).
However this seems to work:
$Extension = "*.jpg"
Get-ChildItem -Path 'C:\Users\ab73541\Documents\' -Directory | ForEach-Object {
$FilesInFolder = #(Get-ChildItem $_.PSPath -Recurse -Include $Extension -File -Force)
$FileSize = $FilesInFolder | Measure-Object -property length -Sum | Select -ExpandProperty Sum
$FileSize = "{0:N2}" -f ($FileSize/1MB) + " MB"
$NumFiles = $FilesInFolder.Count }