I'm Trying to retrieve the exact size of the profile in windows machine.
below is my code and O/P
$profiles = Get-ChildItem C:\Users | ?{Test-path C:\Users\$_\NTUSER.DAT} | Select -ExpandProperty Name
foreach($profile in $profiles)
{
$largeprofile = Get-ChildItem C:\Users\$profile -recurse | Measure-Object -Sum length | Select -ExpandProperty Sum
$largeprofile = [math]::Round(($largeprofile/1MB),2) + "MB"
if($largeprofile -lt 20){Continue}
$object = New-Object -TypeName PSObject
$object | Add-Member -MemberType NoteProperty -Name Name -Value $profile
$object | Add-Member -MemberType NoteProperty -Name "Size(MB)" -Value $largeprofile
($object | fl | Out-String).Trim();Write-Output "`n"
}
O/P
Name : admin
Size(MB) : 34.62
however exact size of the folder is 181MB,powershell is not able to read all the folders and files inside the parent folder, how can I get the exact size which is displayed in a properties of the folder.
Note : For Folders other than the profile folder o/p is correct.
You will have to add the parameter -Force to Get-ChildItem when you are Recursing the directory. From the docs Get-ChildItem the -Force parameter:
Allows the cmdlet to get items that cannot otherwise not be accessed
by the user, such as hidden or system files.
Additionally, you will want to add -ErrorAction SilentlyContinue so you don't get flooded with Access Denied errors. These changes makes your code look like this:
$profiles = Get-ChildItem C:\Users | ?{Test-path C:\Users\$_\NTUSER.DAT} | Select -ExpandProperty Name
foreach($profile in $profiles)
{
$largeprofile = Get-ChildItem C:\Users\$profile -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object -Sum length | Select -ExpandProperty Sum
$largeprofile = [math]::Round(($largeprofile/1MB),2) + "MB"
if($largeprofile -lt 20){Continue}
$object = New-Object -TypeName PSObject
$object | Add-Member -MemberType NoteProperty -Name Name -Value $profile
$object | Add-Member -MemberType NoteProperty -Name "Size(MB)" -Value $largeprofile
($object | fl | Out-String).Trim();Write-Output "`n"
}
Related
When attempting to run script then I got the following the error message.
Error :
Add-Member : Cannot add a member with the name "CAllerID*" because a member with that name already exists. To overwrite the member anyway, add the Force parameter to
your command.
Script :
$output = Get-ADUser -Identity user -Properties givenName, sn, displayname, samaccountname, title
$output | Add-Member -membertype noteproperty -name "CAllerID*" -value $null | Export-CSV -Path "c:\tmp\users.csv" -NoTypeInformation -Encoding UTF8
Add -Force and -PassThru to the Add-Member call:
-Force ensures any existing conflicting properties are overwritten
-PassThru causes Add-Member to output the modified input object
$output | Add-Member -MemberType NoteProperty -Name "CAllerID*" -Value $null -Force -PassThru | Export-CSV -Path "c:\tmp\users.csv" -NoTypeInformation -Encoding UTF8
If you want to further trim the property set returned by Get-ADUser, use Select-Object:
$output | Select-Object -Property givenName,sn,displayName,SAMAccountName,Title | Add-Member -MemberType NoteProperty -Name "CAllerID*" -Value $null -Force -PassThru | Export-CSV -Path "c:\tmp\users.csv" -NoTypeInformation -Encoding UTF8
Works:
$Names = 1..5 | % { new-object psobject | add-member -Type NoteProperty -Name Name -Value "MyName" -PassThru } | group Name -AsHashTable
$Names.MyName
Doesn't work:
$Names = 1..5 | % { new-object psobject | add-member -Type ScriptProperty -Name Name -Value {"MyName"} -PassThru } | group Name -AsHashTable
$Names.MyName
The reason you're unable to access the values in the hash-table by prop name or key-based access is that the keys/props are wrapped in PSObjects. There was a Github issue to fix this in Powershell Core, but it will likely remain forever in Windows Powershell.
If you want to convert to a hash-table after grouping, and want to access some of the grouped values by property name or key-based access do this:
$Names = 1..5 | ForEach-Object {
New-Object PsObject | Add-Member -Type ScriptProperty -Name Name -Value { return "MyName"} -PassThru
} | Group-Object -Property 'Name' -AsHashTable -AsString
$Names.MyName
$Names['MyName']
If you want to convert to a hash-table after grouping, and want to access all the grouped values at once, do this:
$Names = 1..5 | ForEach-Object {
New-Object PsObject | Add-Member -Type ScriptProperty -Name Name -Value { return "MyName"} -PassThru
} | Group-Object -Property 'Name' -AsHashTable
$Names.Values
If you're not converting to a hash-table after the grouping, and want to access the data in $Names.Group, you'll need to expand that property.
$Names = 1..5 | % {
new-object psobject | add-member -Type ScriptProperty -Name Name -Value {"MyName"} -PassThru
} | Group-Object -Property 'Name'
$Names | Select-Object -ExpandProperty Group
I need to list users of a connected drive and it's serial # in an output file. I'll be connecting between 12-24 drives in arrays at a time. I would like to be able to put the assigned drive letters into a variable. And then have the entire script loop for each connected drive. dumping serial + linking it to the users of that drive in a CSV output file
How can I put the assigned drive letters into an array?
$(get-physicaldisk; get-childitem -path (array variable):\Users) | add-content C:\path\to\my\output.csv
almost gets the output I need when I try this on a single drive. But I'd really like to clean it up and only display the important info (PSChildName) excluding all default, public admin accounts to reduce duplicate un-needed info.
I wanted this to work
$(get-physicaldisk | select-object FriendlyName, SerialNumber)-$(get-childitem -path L:\Users| select-object PSChildName)
but it did not
I need it to grab the serial for each drive - and output the users associated with that drive … i'm struggling with making the output look the way I want.
For each - drive in array - output ((serial #) + (users on the drive)) amending my .csv
After much plugging and chugging i'm now here, thanks to everyone's help
function Get-UsersOnDrive([string[]]$DriveLetters){
if (!$DriveLetters){
$DriveLetters = Get-WmiObject Win32_Logicaldisk | %{$_.Name -replace ":", ""}
}
foreach($DriveLetter in $DriveLetters)
{
$SerialNumber = get-partition -DriveLetter $DriveLetter -ErrorAction Ignore | get-disk | select -ExpandProperty SerialNumber
$path = $DriveLetter + ":\Users"
$Users = get-childitem -path $path | select-object PSChildName
$Users | %{
$OutPut = new-object PsCustomObject
$OutPut | Add-Member -MemberType NoteProperty -Name SerialNumber -Value $SerialNumber -PassThru |
Add-Member -MemberType NoteProperty -Name Username -Value $_
return $OutPut
}
}
}
Get-UsersOnDrive -DriveLetters #("C") | Export-Csv -Path C:\sample\Test.csv -NoTypeInformation
Ok so here is what i came up with and its rough
Get-WmiObject Win32_Logicaldisk | %{
$DriveLetter = $_.Name -replace ":", ""
$SerialNumber = get-partition -DriveLetter $DriveLetter | get-disk | select -ExpandProperty SerialNumber
$Users = Get-WmiObject Win32_UserProfile | select -ExpandProperty LocalPath | ?{$_ -like "$DriveLetter*"} | %{
$_ -replace '.*\\'
}
$Users | %{
$OutPut = new-object PsCustomObject
$OutPut | Add-Member -MemberType NoteProperty -Name SerialNumber -Value $SerialNumber -PassThru |
Add-Member -MemberType NoteProperty -Name Username -Value $_
return $OutPut
}
} | Export-Csv -Path C:\sample\Test.csv -NoTypeInformation
A. Get WMI LogicalDisk (gets you the drive letters)
B. Pass the $DriveLetter into a get-partition and get the SerialNumber property value.
C. Get Users Profile path, then find the ones on the current drive and replace everything except for the last slash, which is the username
D. Foreach user on drive we create a Custom Object and add the properties SerialNumber and Username, then return output and export to CSV
Here is a function that you can call to get users on drive as well
function Get-UsersOnDrive([string[]]$DriveLetters){
if (!$DriveLetters){
$DriveLetters = Get-WmiObject Win32_Logicaldisk | %{$_.Name -replace ":", ""}
}
foreach($DriveLetter in $DriveLetters){
$SerialNumber = get-partition -DriveLetter $DriveLetter -ErrorAction Ignore | get-disk | select -ExpandProperty SerialNumber
$Users = Get-WmiObject Win32_UserProfile | select -ExpandProperty LocalPath | ?{$_ -like "$DriveLetter*"} | %{
$_ -replace '.*\\'
}
$Users | %{
$OutPut = new-object PsCustomObject
$OutPut | Add-Member -MemberType NoteProperty -Name SerialNumber -Value $SerialNumber -PassThru |
Add-Member -MemberType NoteProperty -Name Username -Value $_
return $OutPut
}
}
}
Get-UsersOnDrive -DriveLetters #("C","V","F") | Export-Csv -Path C:\sample\Test.csv -NoTypeInformation
If you remove -DriveLetters parameter and the drives then it will check all drives
The following code gets the disk serial number. I am not sure why that is needed. Will this give you a start?
function Get-DiskSerialNumber {
param(
[Parameter(Mandatory = $true,Position=0)]
[string] $DriveLetter
)
Get-CimInstance -ClassName Win32_DiskDrive |
Get-CimAssociatedInstance -Association Win32_DiskDriveToDiskPartition |
Get-CimAssociatedInstance -Association Win32_LogicalDiskToPartition |
Where-Object DeviceId -eq $DriveLetter |
Get-CimAssociatedInstance -Association Win32_LogicalDiskToPartition |
Get-CimAssociatedInstance -Association Win32_DiskDriveToDiskPartition |
Select-Object -Property SerialNumber
}
& openfiles /query /fo csv |
Select-Object -Skip 5 |
ConvertFrom-Csv -Header #('ID','USER','TYPE','PATH') |
Select-Object -Property USER,#{name='DRIVE';expression={$_.PATH.Substring(0,2)}} |
Sort-Object -Property DRIVE,USER -Unique |
Select-Object -Property *,
#{name='SERIALNUMBER';expression={(Get-DiskSerialNumber -Drive $_.DRIVE).SerialNumber}}
I have the following PowerShell script in which I can run to get a good mixed report from Office 365.
$Results = #()
$MailboxUsers = get-mailbox -resultsize unlimited
$Statistics = $MailboxUsers | Get-MailboxStatistics | select *
$Licenses = Get-MsolUser | select *
$Permissions = $MailboxUsers | Get-MailboxPermission | select *
foreach($user in $mailboxusers)
{
$UPN = $user.userprincipalname
$Properties = #{
Name = $user.name
UPN = $UPN
Alias = $user.alias
RecipientTypeDetails = $user.RecipientTypeDetails
Identity = ($Permissions | where {$_.Identity -eq ($user).DisplayName}).Identity
User = ($Permissions | where {$_.Identity -eq ($user).DisplayName}).User
AccessRights = ($Permissions | where {$_.Identity -eq ($user).DisplayName}).AccessRights
IsInherited = ($Permissions | where {$_.Identity -eq ($user).DisplayName}).IsInherited
Deny = ($Permissions | where {$_.Identity -eq ($user).DisplayName}).Deny
IsLicensed = ($Licenses | where {$_.UserPrincipalName -eq ($user).UserPrincipalName}).IsLicensed
TotalItemSize = ($Statistics | where {$_.DisplayName -eq ($user).DisplayName}).TotalItemSize
ItemCount = ($Statistics | where {$_.DisplayName -eq ($user).DisplayName}).ItemCount
License = ($Licenses | where {$_.UserPrincipalName -eq ($user).UserPrincipalName}).Licenses.AccountSkuId
}
$Results += New-Object psobject -Property $properties
}
$results | sort name | fl
However, when I run this, 5 objects Identity, User, AccessRights, IsInherited and Deny all show multiple results mixed into the same output.
Even if I change the last line to this:
$results | sort name | Out-GridView
This also shows the same 5 objects Identity, User, AccessRights, IsInherited and Deny all bunched together.
What I am looking for is to separate the 5 objects Identity, User, AccessRights, IsInherited and Deny onto different lines, and for the rest of the objects, just to repeat e.g. Name, UPN, License, RecipientTypeDetails, TotalItemSize, Alias, IsLicensed and ItemCount would be repeated beside each result in the 5 objects Identity, User, AccessRights, IsInherited and Deny.
This way I can do more things with the output, put it into Excel for example and massage the results.
I would use note properties individually defined like below to build your output results, It works for me and can easily be exported to what ever format you need from here. Check that i got all the properties and in the right order.
foreach($user in $mailboxusers)
{
$UPN = $user.userprincipalname
$match = New-Object -TypeName PSObject
$match | Add-Member -Type NoteProperty -Name "Name" -Value $user.name
$match | Add-Member -Type NoteProperty -Name "UPN" -Value $UPN
$match | Add-Member -Type NoteProperty -Name "Alias" -Value $user.alias
$match | Add-Member -Type NoteProperty -Name "RecipientTypeDetails" -Value $user.RecipientTypeDetails
$match | Add-Member -Type NoteProperty -Name "Identity" -Value ($Permissions | where {$_.Identity -eq ($user).DisplayName}).Identity
$match | Add-Member -Type NoteProperty -Name "User" -Value ($Permissions | where {$_.Identity -eq ($user).DisplayName}).User
$match | Add-Member -Type NoteProperty -Name "AccessRights" -Value ($Permissions | where {$_.Identity -eq ($user).DisplayName}).AccessRights
$match | Add-Member -Type NoteProperty -Name "IsInherited" -Value ($Permissions | where {$_.Identity -eq ($user).DisplayName}).IsInherited
$match | Add-Member -Type NoteProperty -Name "Deny" -Value ($Permissions | where {$_.Identity -eq ($user).DisplayName}).Deny
$match | Add-Member -Type NoteProperty -Name "IsLicensed" -Value ($Licenses | where {$_.UserPrincipalName -eq ($user).UserPrincipalName}).IsLicensed
$match | Add-Member -Type NoteProperty -Name "TotalItemSize" -Value ($Statistics | where {$_.DisplayName -eq ($user).DisplayName}).TotalItemSize
$match | Add-Member -Type NoteProperty -Name "ItemCount" -Value ($Statistics | where {$_.DisplayName -eq ($user).DisplayName}).ItemCount
$match | Add-Member -Type NoteProperty -Name "License" -Value ($Licenses | where {$_.UserPrincipalName -eq ($user).UserPrincipalName}).Licenses.AccountSkuId
$Results += $match
}
I need a script or command that would list all users on a computer plus their home directories and sizes of their home directories. I can do it only for users are looged in. I also managed to get a list of all users :
$adsi = [ADSI]"WinNT://$env:COMPUTERNAME"
$adsi.Children | where {$_.SchemaClassName -eq 'user'} | Select-Object #{n='UserName'
e={$_.Name}}
but I don't know how to get home dir, plus size from that list.
thanks in advance
Here is a powershell loop that outputs objects with the properties you are looking for (Name, LocalPath, FolderSize), formatted as a table. This combines a few techniques to get the values you are looking for.
Get-WmiObject win32_userprofile | % {
try {
$out = new-object psobject
$out | Add-Member noteproperty Name (New-Object System.Security.Principal.SecurityIdentifier($_.SID)).Translate([System.Security.Principal.NTAccount]).Value
$out | Add-Member noteproperty LocalPath $_.LocalPath
$out | Add-Member noteproperty FolderSize ("{0:N2}" -f ((Get-ChildItem -Recurse $_.LocalPath | Measure-Object -property length -sum -ErrorAction SilentlyContinue).sum / 1MB) + " MB")
$out
} catch {}
} | Format-Table