I would like to design my script with variables and I have the problem that as soon as I use the variable, my script no longer works.
In the script part, where I specify the PC name structure, I get the error that my variable is not defined.
In the script part where I want to design the replace with a variable, I get the error: No overload can be found for "replace" and the following number of arguments: "1".
The problem occurs once with the $PCSyntax variable and with the $replace variable.
If I run the affected parts of the script without the variables, then it works.
Script parts without the variables:
Invoke-Command -ComputerName $AD_Server_Name -Credential $Administrator -ScriptBlock {
$AD_Clients = Get-ADComputer -Filter 'Name -like "PC-*"' | select-object -Property Name| Export-Csv (Join-Path $using:Export_Pfad_Extern -ChildPath "Active_Directory_Clients.csv") -NoTypeInformation
}
$WSUS_Clients = Get-WsusComputer -NameIncludes $using:NameSyntax |select FullDomainName| Out-String | % {$_.replace(".domain.local","")} | Out-File -FilePath \\$using:WSUS_Server_Name\C$\users\Administrator\WSUS_Client_list.csv
Script parts with the variables:
$global:PCSyntax = "PC-*"
Get-ADComputer -Filter 'Name -like $using:PCSyntax' | select-object -Property Name| Export-Csv (Join-Path $using:Export_Pfad_Extern -ChildPath "Active_Directory_Clients.csv") -NoTypeInformation
$global:Replace = ".domain.local",""
$WSUS_Clients = Get-WsusComputer -NameIncludes $using:NameSyntax |select FullDomainName| Out-String | % {$_.replace($using:Replace)} | Out-File -FilePath \\$using:WSUS_Server_Name\C$\users\Administrator\WSUS_Client_list.csv
Related
I have a script that I am trying to collect drive letters from a list of servers (as well as used space and free space) and then gridview the results out.
$servers = Get-Content "path.txt"
foreach ($server in $servers) {
Invoke-Command -ComputerName $server {Get-PSDrive | Where {$_.Free -gt 0}}
Select-Object -InputObject usedspace,freespace,root,pscomputername |
Sort-Object root -Descending | Out-Gridview
}
I can get it to display the drive information for each server on the list but gridview does not work. I have tried moving the brackets around (before and after gridview) as well as piping elements but have had no luck.
Can anyone advise me as to what I am doing wrong? I feel like it is something simple but all of the examples I am finding online do not use the foreach command which I think has to do with throwing it off.
Your Select-Object is missing pipeline input - pipe the Invoke-Command call's output to it.
Instead of -InputObject, use -Property:
Note: -InputObject is the parameter that facilitates pipeline input, and is usually not meant to be used directly.
As with Sort-Object, -Property is the first positional parameter, so you may omit -Property in the call below.
foreach ($server in Get-Content "path.txt") {
Invoke-Command -ComputerName $server { Get-PSDrive | Where { $_.Free -gt 0 } } |
Select-Object -Property usedspace, freespace, root, pscomputername |
Sort-Object root -Descending |
Out-Gridview
}
Also note that -ComputerName can accept an array of computer names, which are then queried in parallel, so if you want to query all computers and then call Out-GridView only once, for the results from all targeted computers:
Invoke-Command -ComputerName (Get-Content "path.txt") {
Get-PSDrive | Where Free -gt 0
} |
Select-Object -Property usedspace, freespace, root, pscomputername |
Sort-Object root -Descending |
Out-Gridview
To group the results by target computer, use
Sort-Object pscomputername, root -Descending
If you'd rather stick with your sequential, target-one-server-at-a-time approach, change from a foreach statement - which cannot be used directly as pipeline input - to a ForEach-Object call, which allows you to pipe to a single Out-GridView call:
Get-Content "path.txt" |
ForEach-Object {
Invoke-Command -ComputerName $_ { Get-PSDrive | Where Free -gt 0 }
} |
Select-Object -Property usedspace, freespace, root, pscomputername |
Sort-Object root -Descending |
Out-Gridview
I want to output all hostnames within a network first with a foreach loop, in order (for example) to be able to ping them.
However with the following code I do not get any output in the console. The CSV file will be saved, but what is written in the loop will not be executed.
Does anyone know what the reason for this is and how I can solve it?
Import-Module activedirectory
Get-ADComputer -Filter * -Property * | Select Name | Export-CSV -Path $env:TEMP\ZZZEXPORTE.csv -NoTypeInformation -Encoding UTF8 | ForEach {
$computerName = $_.Name
Write-Host $computerName
Write-Host "----"
}
This occurs because Export-CSV does not output an object. Sometimes cmdlets like this have a -PassThru parameter which you can use to have an object passed along, but thats not the case with Export-CSV, they simply expect it to always be the last cmdlet in the pipeline.
You should instead do this:
$Computers = Get-ADComputer -Filter * -Property * | Select Name
$Computers | Export-CSV -Path $env:TEMP\ZZZEXPORTE.csv -NoTypeInformation -Encoding UTF8
$Computers | ForEach {
$computerName = $_.Name
Write-Host $computerName
Write-Host "----"
}
You could also do this:
Get-ADComputer -Filter * -Property * | Select Name | ForEach {
$computerName = $_.Name
Write-Host $computerName
Write-Host "----"
$_
} | Export-CSV -Path $env:TEMP\ZZZEXPORTE.csv -NoTypeInformation -Encoding UTF8
Noting that we have to add $_ to our ForEach-Object loop so that it outputs the current item to the pipeline, but that our Write-Host statements don't effect the pipeline because they are writing to the console only. To be honest though, this is a bit harder to follow for anyone else reading your code.
I have a PowerShell script below
$ous = 'ou=office,dc=xxx,dc=com',`
'ou=shop0,dc=xxx,dc=com',`
'ou=shop1,dc=xxx,dc=com',`
'ou=shop2,dc=xxx,dc=com'
$outfile = 'c:\work\userinfo.csv'
New-Item -Force -type "file" -Path 'c:\work\userinfo.csv'
$ous | ForEach {
Get-ADUser -Filter * -SearchBase $_ |
Select-Object -Property CN,`
DisplayName,`
GivenName,`
Surname,`
SamAccountName,`
PasswordExpired,`
mail,`
Description,`
Office,`
EmployeeNumber,`
Title |
Sort-Object -Property Name |
export-csv -Append $outfile -NoTypeInformation
}
Then when I run it, I got error message "New-Item: access to the path c:\work\userinfo.csv" is denied.
What's the cause for this error?
Update:
In my case, somehow, PowerShell is case-sensitive....the output folder name is uppercase, in my script is lowercase, it works after I match them.
I am bypassing the reason for the error ( of which I'm not sure of the cause.). Another way to get what you want
each time I run script, I could get an fresh result without previous results
You just need to move the output code outside the loop and remove the append. Pipeline handles the Append for you.
$ous | ForEach {
Get-ADUser -Filter * -SearchBase $_ |
Select-Object -Property CN,`
DisplayName,`
GivenName,`
Surname,`
SamAccountName,`
PasswordExpired,`
mail,`
Description,`
Office,`
EmployeeNumber,`
Title
} | Sort-Object -Property Name |
export-csv -Append $outfile -NoTypeInformation
Noticed something
You are not calling all the properties you are using in your select statement. That should lead to some null columns in your output. I would update your code to something like this.
$props = "CN","DisplayName","GivenName","Surname","SamAccountName","PasswordExpired","mail","Description","Office","EmployeeNumber","Title"
$ous | ForEach-Object {
Get-ADUser -Filter * -SearchBase $_ -Properties $props | Select-Object $props
} | Sort-Object -Property Name |
export-csv $outfile -NoTypeInformation
I'm trying to simply get a list of computers and their OU's from a CSV file of computer names
Add-PSSnapin quest.activeroles.admanagement
$results = #()
$computers = Get-Content "computers.csv"
foreach ($computer in $computers)
{
$results += Get-QADComputer $computer | select name, parentcontainer
}
$results = Export-CSV -path "computerswithous.csv"
But it errors out asking me to supply values. How can I simply output this data to a CSV file?
You did not include it in the post but is this what you were getting:
cmdlet Export-Csv at command pipeline position 1
Supply values for the following parameters:
InputObject:
Simple answer is this line
$results = Export-CSV -path "computerswithous.csv"
Should most likely be this
$results | Export-CSV -path "computerswithous.csv"
In your example Export-CSV has no input data which is what your prompt (not error) is requesting. You actually want to pipe the $results to the CSV file.
You also could do away with that construct as well and just use standard pipeline to get what you are looking for.
Add-PSSnapin quest.activeroles.admanagement
Get-Content "computers.csv" | ForEach-Object{Get-QADComputer $_} |
Select Name,ParentContainer | Export-CSV -Path "computerswithous.csv" -NoTypeInformation
You don't need that intermediate collection ($results) at all. Just wrap the foreach loop in a sub-expression, and send it on to the pipeline.
Add-PSSnapin quest.activeroles.admanagement
$computers = Get-Content "computers.csv"
$(foreach ($computer in $computers)
{
Get-QADComputer $computer | select name, parentcontainer
}) | Export-CSV -path "computerswithous.csv"
I've been working on a simple script to read the win32_product off a remote PC, which is working fine. However, I would like the query to ignore some common applications on my domain. I've been building a list of apps and their IdentifyingNumber and putting the IdentifyingNumber into a txt file. I load the text file into a variable with the script and I'm trying to figure out how to get the query to filter each item in the variable...so I have this::
$PC = Read-Host "What is target workstation..."
$logfile = "d:\$PC.txt"
$ignore = [IO.File]::ReadAllText("D:\INCOMING\AppListing\ignore.txt")
get-wmiobject -class win32_product -computer $PC | where {$_.IdentifyingNumber -notlike $ignore} | Select Name, IdentifyingNumber | sort-object Name | export-csv $logfile -encoding "unicode"
However, this is not filtering at all, not even the first or last item from the txt file. I used write-host $ignore to verify it is loading the items...but I am at a lost as to how to make this work. Perhaps a foreach loop? I can't find anything about putting a foreach loop into a where filter though...
Thanks for the assistance...
If the file is like this:
aRandomId
anotherRandonId
...
with one id on each line and nothing else, then try this using -notlike with wildcards on the ends. Ex:
$PC = Read-Host "What is target workstation..."
$logfile = "d:\$PC.txt"
$ignore = [IO.File]::ReadAllText("D:\INCOMING\AppListing\ignore.txt")
get-wmiobject -class win32_product -computer $PC | where { $ignore -notlike "*$($_.identifyingnumber)*" } |
Select Name, IdentifyingNumber | sort-object Name | export-csv $logfile -encoding "unicode"
You could also read your file as an array using ReadAllLines like you would have had to do if you wanted to use a foreach-loop or -notcontains. Ex:
$PC = Read-Host "What is target workstation..."
$logfile = "d:\$PC.txt"
$ignore = [IO.File]::ReadAllLines("D:\INCOMING\AppListing\ignore.txt")
get-wmiobject -class win32_product -computer $PC | where { $ignore -notcontains $_.identifyingnumber } |
Select Name, IdentifyingNumber | sort-object Name | export-csv $logfile -encoding "unicode"
$prods = Compare-Object -ReferenceObject (Get-Content $file) -DifferenceObject ((Get-WmiObject -Class Win32_Product -Computer $computer).IdentifyingNumber) -PassThru
Compare-Object is a great Cmdlet.