I wrote a script to copy files to the "All Users" desktop or "Public Desktop"
However we have a mixed environment. Some people are using Windows XP and other people are using Windows 7.
$SOURCE = "I:\Path\To\Folder\*"
$DESTINATION7 = "c$\Users\Public\Desktop"
$DESTINATIONXP = "c$\Documents and Settings\All Users\Desktop"
$computerlist = Get-Content I:\Path\To\File\computer-list.csv
$results = #()
$filenotthere = #()
$filesremoved = #()
foreach ($computer in $computerlist) {
if((Test-Connection -Cn $computer -BufferSize 16 -Count 1 -ea 0 -quiet))
{
Write-Host "\\$computer\$DESTINATION\"
Copy-Item $SOURCE "\\$computer\$DESTINATION\" -Recurse -force
} else {
$details = #{
Date = get-date
ComputerName = $Computer
Destination = $Destination
}
$results += New-Object PSObject -Property $details
$results | export-csv -Path I:\Path\To\logs\offline.txt -NoTypeInformation -Append
}
}
DESTINATION is empty. Expanding on Keith's suggestion:
foreach ($computer in $computerlist) {
if((Test-Connection -Cn $computer -BufferSize 16 -Count 1 -ea 0 -quiet))
{
$OS = Get-WmiObject -Computer $computer -Class Win32_OperatingSystem
if($OS.caption -like '*Windows 7*'){
$DESTINATION = $DESTINATION7
}
if($OS.caption -like '*Windows XP*'){
$DESTINATION = $DESTINATIONXP
}
}
}
This could avoid the error you're getting also. empty $DESTINATION.
In your foreach loop through $computerlist you can grab the OS Caption for each computer by using WMI:
$OS = Get-WmiObject -Computer $computer -Class Win32_OperatingSystem
Ant then check the $OS
if($OS.caption -like '*Windows 7*'){
#Code here for Windows 7
}
#....
I had a slightly different goal...But thanks for the basics.
del C:\scripts\OS.csv
$computerlist = Get-Content c:\scripts\computerlist.csv
foreach ($computer in $computerlist) {
if((Test-Connection -Cn $computer -BufferSize 16 -Count 1 -ea 0 -quiet))
{
Get-WMIObject Win32_OperatingSystem -ComputerName $computer |
select-object CSName, Caption, CSDVersion, OSType, LastBootUpTime, ProductType| export-csv -Path C:\Scripts\OS.csv -NoTypeInformation -Append
}
}
Related
Noob here, I need to extract some data from a cim interrogation of a list of servers, however the csv output is just the same reiteration of the local server, with the sum total equaling the number of lines in the input file. I think I'm doing something wrong with the array but Ive been beating my head. Help?
$ErrorActionPreference = 'SilentlyContinue'
#Define Some Variables
$importpath = "c:\directory1"
$workingpath = "c:\directory2"
#Do Some Filtering
Import-CSV -Path "$importpath\somefile.csv" | where {$_.Powerstate -ne "PoweredOff"} | where Guest -notlike *somestring* | Export-Csv "$workingPath\PRODUCTION.csv" -NoTypeInformation
Import-csv -Path "$workingPath\PRODUCTION.csv" | Select-Object -Property Name | Export-Csv -Path "$workingpath\SERVERS.csv" -NoTypeInformation
#Create final input foreach routine
Import-CSV -Path "$workingpath\SERVERS.csv" | Out-file $workingpath\SERVERS.txt
$servers = Get-Content -path "$workingpath\SERVERS.txt"
$results = foreach ($server in $servers) {
Get-CimInstance -ClassName win32_OperatingSystem -ErrorAction SilentlyContinue | Select-Object *
}
$results | Export-Csv -Path "$workingPath\PRODUCTIONRESULTS.csv" -NoTypeInformation -Append
Try including the computername when you run the Get-CimInstance command
$results = foreach ($server in $servers) {
Get-CimInstance -ComputerName $server -ClassName win32_OperatingSystem -ErrorAction SilentlyContinue | Select-Object *
}
I'm using this Powershell script to retrieve info of remote servers from a central server.
In this case, there are about 150 servers on Active Directory:
$Servers = Get-ADComputer -Filter 'Name -like "...*"' | Select-Object -ExpandProperty Name
foreach ($computer in $Servers)
{
try
{
$ping = Test-Connection -ComputerName $computer -count 1 -ErrorAction Stop
$IP = ($ping.IPV4Address).IPAddressToString
$hardware = Get-CimInstance -Class Win32_ComputerSystem -ComputerName $computer -ErrorAction Stop
$totalMemory = (Get-CimInstance Win32_PhysicalMemory -ComputerName $computer | Measure-Object -Property capacity -Sum).sum /1gb
$os = Get-CimInstance -Class Win32_OperatingSystem -ComputerName $computer
$cpu = Get-CimInstance -Class Win32_processor -ComputerName $computer | Group-Object -Property Name |
Select-Object -Property Name,
#{Name = 'TotalSockets'; Expression = {$_.Count}},
#{Name = 'TotalCores'; Expression = {($_.Group | Measure-Object -Property NumberOfCores -Sum).Sum}},
#{Name = 'TotalLogicalProcessors'; Expression = {($_.Group | Measure-Object -Property NumberOfLogicalProcessors -Sum).Sum}}
#$disks = Get-WmiObject Win32_Volume -ComputerName $computer -Filter "DriveType='3'" | Sort-Object Name
# create new custom object to keep adding store information to it
$Result = New-Object -TypeName PSCustomObject -Property #{
ComputerName = $computer.ToUpper()
IPAddress = $IP
Manufacturer = $hardware.Manufacturer
Model = $hardware.Model
ADDescription = (Get-ADComputer -Identity $computer -Properties Description).Description -join ';'
ProductName = $os.Caption
OSVersion = $os.version
BuildNumber = $os.BuildNumber
OSArchitecture = $os.OSArchitecture
Domain = $hardware.Domain
'RAM (GB)' = $totalMemory
CPU = $cpu.Name
CPUTotalSockets = $cpu.TotalSockets
CPUTotalCores = $cpu.TotalCores
CPUTotalLogicalProcessors = $cpu.TotalLogicalProcessors
CPUVirtualizationFirmwareEnabled = (Get-CimInstance -Class Win32_processor -ComputerName $computer).VirtualizationFirmwareEnabled -join ','
}
# Column ordering, re-order if you like
<#$colOrder = 'ComputerName', 'IPAddress', 'Manufacturer', 'Model', 'ADDescription',
'ProductName', 'OSVersion', 'BuildNumber', 'OSArchitecture',
'Domain', 'RAM (GB)', 'CPU', 'CPUTotalSockets', 'CPUTotalCores',
'CPUTotalLogicalProcessors', 'CPUVirtualizationFirmwareEnabled'#>
# Return all your results
#$Result | Select-Object -Property $colOrder
$Result | Select-Object "ComputerName", "IPAddress", "Manufacturer", "Model", "ADDescription", "ProductName", "OSVersion", "BuildNumber",
"OSArchitecture", "RAM (GB)", "CPU", "CPUTotalSockets", "CPUTotalCores", "CPUTotalLogicalProcessors", "CPUVirtualizationFirmwareEnabled", "Domain" |
Export-Csv -Path "C:\SQL\Get-Inventory.csv" -Delimiter '|' -Append -NoTypeInformation
#$disks | Format-Table DriveLetter, Label, #{Name='Size(GB)'; Expression={[decimal]('{0:N0}' -f($_.Capacity/1gb))}}, #{Name='FreeSpace(GB)'; Expression={[decimal]('{0:N0}' -f($_.FreeSpace/1gb))}}
}
catch
{ Write-Output "--- $computer ---" $Error[0] `n | Add-Content -Path C:\SQL\UnreachableServers.txt }
}
The Powershell's process uses an average of 50/75 Mb of RAM. It's possible to reduce the RAM usage?
I accept any kind of advice given my little experience on Powershell :)
Thanks in advance.
Alessandro
i need some help in order to complete the script, i have already script which deleting specific profiles on the remote server, but i want o add time frame. Example: if the profile was not used for more than 120 days delete it.
Function Get-OldProfiles {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$True,Position=1)] [string]$computerName
)
PROCESS {
foreach ($computer in $computerName) {
Write-host -ForegroundColor Yellow "Housekeeping on $computer"
Write-host -ForegroundColor Yellow "Mapping drive \\$computer\c$"
$drive = New-PSDrive -Name $computer.replace(".","-") -PSProvider FileSystem -Root \\$computer\C$
Write-host -ForegroundColor Yellow "Checking windows version"
#Cheking windows version
$version = (Get-WmiObject -ComputerName $computer -Class Win32_OperatingSystem).version
Write-host -ForegroundColor Yellow "Windows version $version"
#Profile Deleting area.
if ($version -ge 6) {
Write-host -ForegroundColor Yellow "Getting profiles from WMI"
$profiles = Get-WmiObject -ComputerName $computer Win32_UserProfile -filter "LocalPath Like 'C:\\Users\\%'" | Where-object localpath -Match 'B.{5}R$'| Select-Object {$_.ConvertToDateTime($_.LastUseTime) -lt (Get-Date).AddDays(-2)}
if ($profiles -ne $null) {
$profiles | foreach {
Write-host -ForegroundColor Red ("Deleting profile: " + $_.LocalPath)
#$_.Delete()
}
}
}
}
}
}
I've tried this:
$profiles= Get-WmiObject -ComputerName $computer -class Win32_UserProfile -filter "Special = False -and LocalPath Like 'C:\\Users\\%'" | Where-object localpath -Match 'B.{5}R$' | Where {$_.ConvertToDateTime($_.LastUseTime) -lt (Get-Date).AddDays(-120)}
But it returns an error
Get-WmiObject : Invalid query "select * from Win32_UserProfile where Special = False -and LocalPath Like 'C:\\Users\\%'"
At line:22 char:24 + $profiles= Get-WmiObject -ComputerName $computer -class Win32_UserPr ...
You can't use -and in a WQL-filter, it's just AND. Try:
$profiles = Get-WmiObject -ComputerName $computer -Class Win32_UserProfile -filter "Special = False AND LocalPath Like 'C:\\Users\\%'" |
Where-Object { ($_.localpath -Match 'B.{5}R$') -and ($_.ConvertToDateTime($_.LastUseTime) -lt (Get-Date).AddDays(-120)) }
I have this code that generates a list of all the shares and the size however can not generate a txt with this information or the shared location
$servers = #("servername")
$sizes = #()
foreach($server in $servers) {
write-host "Server: $server"
(gwmi -class Win32_Share -ComputerName $server -filter "Type = 0" |
% {
write-host " share: $($_.Name)"
$s = gci \\$server\$($_.Name) -recurse -force | Measure-Object -Property length -Sum
New-Object PSObject -property #{Name=$_.Name; Server=$server; TotalSize=$s.Sum }
})
}
And this not only shows me the size and generates txt size and can generate txt
Get-WmiObject Win32_share -computer server01 | FT "server01", path, name > ServerShares.txt
Get-WmiObject Win32_share -computer server02 | FT "server02", path, name >> ServerShares.txt
Someone could help me to create only one that does everything
In your New-Object you just need to add additional properties to get the information you want:
If you're not running PowerShell v3, remove [Ordered]
$servers = #("servername")
$sizes = #()
foreach($server in $servers)
{
write-host "Server: $server"
# Get all shares
$shares = Get-WmiObject -class Win32_Share -ComputerName $server -filter "Type = 0"
# go through each share
foreach($share in $shares)
{
write-host " share: $($share.Name)"
# Get size of share
$size = Get-ChildItem -Path "\\$server\$($_.Name)" -recurse -force | Measure-Object -Property length -Sum
# Create a new object to store information
New-Object PSObject -property ([ordered]#{
# Name of share
Name = $share.Name
# Share path
Path = $share.path
# What server share is on
Server = $server
# Total size of share
TotalSize = $size.Sum
# Change this path to where you want the file to be saved to
}) | Export-Csv -Path C:\ShareDetails.csv -NoTypeInformation -Append
}
}
I made a small revision to #Bluecakes response in order to use COM instead of .NET to capture the size information. This overcomes the path-length issues.
# Get size of share
# $size = Get-ChildItem -Path "$($share.Name)" -recurse -force | Measure-Object -Property length -Sum
$objFSO = New-Object -com Scripting.FileSystemObject
$size = "{0:N2}" -f (($objFSO.GetFolder("$($share.Name)").Size) / 1MB)
Then you also need to remove ".sum"
# Total size of share
TotalSize = $size
I'm trying to set the properties of a local account on a bunch of servers to "password never expires". This is the best I could figure out. I keep getting:
Get-WmiObject : Invalid parameter
At C:\Users\xxxxxx\AppData\Local\Temp\4f06fa1c-61da-4c65-ac0b-a4167d83d51c.ps1:4 char:14
+ Get-WmiObject <<<< -class Win32_UserAccount -Filter "name = 'localaccount'" - ComputerName $server | Set-WmiInstance -Argument #{PasswordExpires = 0}
+ CategoryInfo : InvalidOperation: (:) [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
--------- Here's what I am trying ------------
$servers = Get-Item c:\list.txt
foreach ($server in $servers)
{
Get-WmiObject -class Win32_UserAccount -Filter "name = 'localaccount'" -ComputerName $server | Set-WmiInstance -Argument #{PasswordExpires = 0}
}
Thank you!
Your mistake is in this line:
$servers = Get-Item c:\list.txt
The Get-Item cmdlet returns a FileInfo object, not the content of the file. For reading the content into a variable you need the Get-Content cmdlet.
This should work:
Get-Content 'c:\list.txt' | % {
gwmi Win32_UserAccount -Computer $_ -Filter "name='localaccount'" |
Set-WmiInstance -Argument #{PasswordExpires = $false}
}
You could also do the property change like this (source):
Get-Content 'c:\list.txt' | % {
$account = gwmi Win32_UserAccount -Computer $_ -Filter "name='localaccount'"
$account.PasswordExpires = $false
$account.Put()
}