How can I read multiple computer descriptions? - powershell

I want to create a script which reads all the computernames from a CSV file. And from all of these, I want the description. Also it should be exported in a single CSV.
This is what I tried but...
$path = Split-Path -Parent $MyInvocation.MyCommand.Definition
$path_import_csv = $path + "\" + "Computernamen.csv"
$path_export_csv = $path + "\" + "Alessio.csv"
$computernames = Import-Csv $path_import_csv
foreach ($computername in $computernames) {
Get-ADComputer -SearchBase "OU=1,OU=2,OU=3,DC=my,DC=domain" -Properties * |
Select -Expand description |
Export-Csv -Path $path_export_csv -Append -Delimiter ";" -NoTypeInformation -Force
}

From your comment I gather that file Computernamen.csv is not a CSV file at all, but just a text file with computer names each on a separate line.
In that case, you do not use Import-Csv, but Get-Content to retrieve an array of computer names.
Also (others already made that clear) you are not using the $computername variable in the foreach loop at all AND by adding the -ExpandProperty switch to the Select-Object cmdlet, you are not receiving an object with property Description, but just the description as string .
For outputting a CSV with Export-Csv, you need to have a (series of) objects.
Also, I would recommend using the Join-Path cmdlet for creating file paths instead of contatenating string with + so you don't have to worry about possible missing backslashes.
Instead of $MyInvocation.MyCommand.Definition you can also use the $PSScriptRoot variable to get the current script path.
In Windows PowerShell 2.0, this variable is valid only in script modules (.psm1).
Beginning in Windows PowerShell 3.0, it is valid in all scripts.
$path = Split-Path -Parent $MyInvocation.MyCommand.Definition # or use $PSScriptRoot
$path_import_csv = Join-Path -Path $path -ChildPath 'Computernamen.csv'
$path_export_csv = Join-Path -Path $path -ChildPath 'Alessio.csv'
$computernames = Get-Content $path_import_csv
$searchBase = 'OU=1,OU=2,OU=3,DC=my,DC=domain'
$result = foreach ($computername in $computernames) {
# it is bad practice to use -Properties * if all you need is a small set of properties
$computer = Get-ADComputer -Filter "Name -eq '$computername'" -SearchBase $searchBase -Properties Name, Description -ErrorAction SilentlyContinue
# did we find a computer by that name?
if ($computer) {
# output an object with the two selected properties to get collected in the $result variable
$computer | Select-Object Name, Description
}
else {
Write-Host "A computer with name '$computername' does not exist."
}
}
# output the result on console
$result | Format-Table -AutoSize
# save the result as proper CSV file
$result | Export-Csv -Path $path_export_csv -Delimiter ';' -NoTypeInformation -Force

Related

PSCustomObject Check Multiple Computers for folder

I am trying to check for presence of a particular folder "appdata\Local\Packages\ActiveSync" in each of the profile folders that are returned for each of the computer by the below script.Searching through various forums I got the script below and need further assistance to eventually output it to a file with results of Test-Path against each computer name and corresponding profile path.
e.g. \\Computer1\C:\users\John\appdata\Local\packages\ActiveSync False
Invoke-Command -Computer (get-content c:\temp\servers.txt) -ScriptBlock {
Get-childItem 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList' |
% {Get-ItemProperty $_.pspath }} | Select pscomputername,profileimagepath |
Where-Object { $_.ProfileImagePath -like "C:\users*" } | Out-File c:\temp\profiles.csv
For this, I think I would use a loop to go through all user path strings like below:
Invoke-Command -ComputerName (Get-Content -Path 'c:\temp\servers.txt') -ScriptBlock {
$regPath = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\*'
Get-ItemPropertyValue -Path $regPath -Name 'ProfileImagePath' -ErrorAction SilentlyContinue |
Where-Object { $_ -like 'C:\Users*' } | ForEach-Object {
# combine the value with the rest of the path to form a LOCAL path
$path = Join-Path -Path $_ -ChildPath 'AppData\Local\Packages\ActiveSync'
[PsCustomObject]#{
ComputerName = $env:COMPUTERNAME
Path = '\\{0}\{1}' -f $env:COMPUTERNAME, ($path.Replace(":", "$")) # UNC format
Exists = Test-Path -Path $path -PathType Container
}
}
} | Export-Csv -Path 'c:\temp\profiles.csv' -NoTypeInformation
Please note that if the output should be a structured CSV file, you need to use Export-Csv on the resulting objects instead of Out-File.
Also you may need to append parameter -Credential to the Invoke-Command call where you can give it administrative credentials.

PowerShell - Double loop possible?

I want to compress a directory in a specific place.
The source path is : \\$Computers\Users\$Names
I want than for each computers a copy of each users directory in the sources path of each computers
I tried to use a foreach loop like :
$Computers = Get-ADComputer -Filter "Name -like 'PC*'" | Select-Object -ExpandProperty Name
$Names = Get-aduser -filter * | Select-Object -ExpandProperty givenname
Foreach($Computer in $Computers)
{
Compress-Archive -Path \\$Computer\Users\* -DestinationPath C:\Saves\\$Computer\Test.zip -Force
}
This actually work, but I don't know how can I add a second loop inside the loop.
If anyone can just explain me the function or just some advises please for trying to do that.
Thank you for your time.
You're approaching the problem with the wrong logic, you do need an inner loop, however, instead of attempting to compress a user profile that you don't know for sure is there you can instead query the remote computer's Users folder to see which ones are there and compress only those ones:
$Computers = (Get-ADComputer -Filter "Name -like 'PC*'").Name
# Add the profiles you want to exclude here:
$toExclude = 'Administrator', 'Public'
$params = #{
Force = $true
CompressionLevel = 'Optimal'
}
foreach($Computer in $Computers)
{
$source = "\\$Computer\Users"
Get-ChildItem $source -Exclude $toExclude -Directory | ForEach-Object {
$params.LiteralPath = $_.FullName
# Name of the zipped file would be "ComputerExample - UserExample.zip"
$params.DestinationPath = "C:\Saves\$computer - {0}.zip" -f $_.Name
Compress-Archive #params
}
}

Compare a folder of Images to a CSV file in Powershell

Okay so we are setting up a card access system that looks at the Active Directory Users thumbnailPhoto attribute. I am creating an audit system that exports the Users and compares them with the JPG images. If the image exists but there isn't a correlating user, it moves the image into an archive to be reviewed. The goal is to remove old employee photos into a folder incase of later hire. I can't get the image to move into another folder if it matches a name in the CSV. Here is the entire code:
<#Write Users to a CSV File #>
$adUsers = get-aduser -filter * -properties displayname | select displayname | export-csv -path PATHWAY.CSV -notypeinformation -encoding unicode
$keepImages = #()
$removeImages = #()
[System.Collections.ArrayList]$arrA = (Get-Childitem -Filter * -path PATHWAY).Basename
[System.Collections.ArrayList]$arrB = Get-Content PATHWAY.CSV
foreach ($itemA in $arrA) {
if ($arrB -ne $itemA) {
$arrB.Remove($itemA)
$removeImages += $itemA }}
$removeImages |out-file -FilePath PATH.csv
<# PUT THE FILES INTO AN ARCHIVE #>
--Cant get it to move here, note I am brand new to Powershell, its not like python at all--
You can try this. I have added inline comments to hopefully explain how it works:
$ImagesFolder = 'D:\UserImages'
$OldUserImages = 'D:\UserImages\OldUsers'
# test if the path to move old images exists and if not create it
if (!(Test-Path -Path $OldUserImages -PathType Container)) {
$null = New-Item -Path $OldUserImages -ItemType Directory
}
# get a list of ADUser display names
$adUsers = Get-ADUser -Filter * -Properties DisplayName | Select-Object -ExpandProperty DisplayName
# get an array of FileInfo objects of the user images currently in the $ImagesFolder.
# filter out only those that do not have a basename that correlates to any of the users DisplayName
# and move these to the $OldUserImages folder.
# Tip: if for instance all are of type JPG, add -Filter '*.jpg' to the Get-ChildItem cmdlet.
Get-ChildItem -Path $ImagesFolder -File |
Where-Object { $adUsers -notcontains $_.BaseName } |
Move-Item -Destination $OldUserImages -Force
If you want to keep track of the images you have moved, you can extend the above like:
$moved = Get-ChildItem -Path $ImagesFolder -File |
Where-Object { $adUsers -notcontains $_.BaseName } |
ForEach-Object {
$file = $_.FullName
$_ | Move-Item -Destination $OldUserImages -Force
[PsCustomObject]#{
'File' = $file
'MovedTo' = $OldUserImages
}
}
# show result on screen
$moved | Format-Table -AutoSize
# write to CSV file
$out = '{0:yyyy-MM-dd}_MovedImages.csv' -f (Get-Date)
$moved | Export-Csv -Path (Join-Path -Path $ImagesFolder -ChildPath $out) -NoTypeInformation

Output filename weirdly

I've written a script to extract a list of all AD groups name, that then feeds it into the next section which exports a number of CSV files based on the name of the group:
import-module active directory
New-Item -Path "c:\" -Name "ADlist" -ItemType "directory"
get-adgroup -filter * | sort name | select Name | export-csv -Path c:\ADlist\adlist.csv
$ADlist = Import-Csv -Path "c:\ADlist\adlist.csv"
foreach ($ADgroup in $ADlist)
{
$export = get-ADGroupMember -identity $ADgroup.name | select name |Export-Csv "$ADgroup.csv" -notypeinformation
}
this works, however, the csv names are outputting weirdly and looks similar to:
#{Name=$ADgroup}
instead of simply
$ADgroup
is there a way to correct this to output as such?
Your last Export-Csv "$ADgroup.csv" is stringifying your $ADGroup object. Since that object has a property called Name and an associated value, you are seeing the result in that format. You should change that to the following:
$export = Get-ADGroupMember -Identity $ADgroup.name |
Select-Object Name |
Export-Csv "$($ADgroup.Name).csv" -NoTypeInformation
You can see this behavior by just surrounding a custom object in quotes or using Write-Host.
"$ADgroup"
Write-Host $ADgroup

Delete multiple files or folders from a CSV file that contain more than one columns (Powershell)

I need some help with script that will delete AD Disabled users Home Folders and Roaming Profiles folders on the Server (DC).
Steps That I already done, I create a powershell command:
Import-Module ActiveDirectory
Get-ADUser -SearchBase "OU=Marked for Deletion,OU=Disable Users,DC=******,DC=com" -Filter * -Property * |
Select-Object -Property homeDirectory,profilePath | Export-CSV -Path .\Remove.csv
This Command export the properties of home folders and roaming profile folders of disabled users.
Now' the CSV file contains two colmuns, one is "homeDirectory" and second "profilePath"
The Problem is, when i execute this script, i get error.
$folders = Get-Content "C:\lab\remove.csv"
foreach ($homeDirectory in $folders) {
Remove-Item -Path $homeDirectory -force -Recurse
}
foreach ($profilePath in $folders) {
Remove-Item -Path $profilePath -force -Recurse
}
write-host -foregroundcolor yellow "Delete action complete"
Can somebody help me with this, I will appreciate it.
First I would remove the type information from your CSV like so:
Import-Module ActiveDirectory
Get-ADUser -SearchBase "OU=Marked for Deletion,OU=Disable Users,DC=******,DC=com" -Filter * -Property * |
Select-Object -Property homeDirectory,profilePath |
Export-CSV -Path .\Remove.csv -NoTypeInformation
Then for your delete code I would use this:
Import-Csv "C:\lab\remove.csv" | % {
Remove-Item -Path $_.homeDirectory -force -Recurse
Remove-Item -Path $_.profilePath -force -Recurse
}
write-host -foregroundcolor yellow "Delete action complete"
The problem with your code is that you are not looping through a column, you looping by line and then doing it twice. To do it your way you would need to split the line at the comma.