Here get-adgroups returns false when querying from script while it returns true when run manually using the very same PowerShell ISE Window. Please see the following code which produces the error. Group, OU and DN exist. Quite likely no Typo. Reproducible by manually running the command (see further below), which works fine.
Import-Module ActiveDirectory
$Group="ProductInternalInstallProductOnNextLogin"
$BaseDN="OU=Product,DC=int,DC=Domain,DC=de"
write-host "get-adgroup -Filter DistinguishedName -eq CN=$Group,$BaseDN"
$Result=get-adgroup -Filter {(DistinguishedName -eq "CN=$Group,$BaseDN")}
if($Result)
{
write-host "Group $Group found"
}
else
{
write-host "Group $Group not found, trying to create $Group"
New-ADGroup -path "$BaseDN" -GroupScope Global -name $Group
if (!$?)
{
write-host "ERROR creating new group $Group"
exit
}
}
This results in the following output where you can see the error:
____________________________________________________________________________________________________________________________________________________________________________________________________________________
PS C:\Users\MyName.INT> G:\DevPath\Tools\PowerShell-Scripte\Unbenannt2.ps1
get-adgroup -Filter DistinguishedName -eq CN=ProductInternalInstallProductOnNextLogin,OU=Product,DC=int,DC=Domain,DC=de
Group ProductInternalInstallProductOnNextLogin not found, trying to create ProductInternalInstallProductOnNextLogin
New-ADGroup : Die angegebene Gruppe ist bereits vorhanden
Bei G:\DevPath\Tools\PowerShell-Scripte\Unbenannt2.ps1:13 Zeichen:16
+ New-ADGroup <<<< -path "$BaseDN" -GroupScope Global -name $Group
+ CategoryInfo : NotSpecified: (CN=ProductInte...nt,DC=Domain,DC=de:String) [New-ADGroup], ADException
+ FullyQualifiedErrorId : Die angegebene Gruppe ist bereits vorhanden,Microsoft.ActiveDirectory.Management.Commands.NewADGroup
ERROR creating new group ProductInternalInstallProductOnNextLogin
____________________________________________________________________________________________________________________________________________________________________________________________________________________
How can New-ADGroup fail if I'm only running it in case the group is not there? PowerShell is running in German here, so the error message "New-ADGroup : Die angegebene Gruppe ist bereits vorhanden" means "This group already exists".
To verify this, I ran this manually in the console, where it works out fine:
PS C:\Users\MyName.INT> write-host "the following command was run manually from the commandline of the PowerShellISE"
$Result=get-adgroup -Filter {(DistinguishedName -eq "CN=ProductInternalInstallProductOnNextLogin,OU=Product,DC=int,DC=Domain,DC=de")}
write-host $Result
which produces the correct output:
the following command was run manually from the commandline of the PowerShellISE
CN=ProductInternalInstallProductOnNextLogin,OU=Product,DC=int,DC=Domain,DC=de
In my struggling I tried also
try {get-adgroups [...]} catch {new-adgroup[...]}
but that didn't work out either.
Have you tried pulling the string concatenation for your target group outside the Get-ADGroup command? I was actually able to replicate your issue from my PowerShell ISE session. When I updated the 'filter' it cleared things up and I was able to retrieve the information successfully.
Original:
$Group = "ProductInternalInstallProductOnNextLogin"
$BaseDN = "OU=Product,DC=int,DC=Domain,DC=de"
$Result = get-adgroup -Filter {(DistinguishedName -eq "CN=$Group,$BaseDN")}
Modified:
$Group = "ProductInternalInstallProductOnNextLogin"
$BaseDN = "OU=Product,DC=int,DC=Domain,DC=de"
$Target = "CN=" + $Group + "," + $BaseDN
$Result = get-adgroup -Filter {DistinguishedName -eq $Target}
Related
My PowerShell script just checks multiple servers to make sure the input* and output* directories are clear of any files.
I'm simply trying to output to console the results of a GCI call prior to throwing an error message. However, when I uncomment the "throw" line, the $inputFiles and $outputFiles no longer output to the console. Below is the code:
$allServers = #(
"server1.com",
"server2.com")
foreach ($server in $allServers) {
$inputFiles = Get-ChildItem -Path "\\$server\C$\jobs\statements\input*\" -Recurse | Where-Object {! $_.PSIsContainer } | Select FullName
$outputFiles = Get-ChildItem -Path "\\$server\C$\jobs\statements\output*\" -Recurse | Where-Object {! $_.PSIsContainer } | Select FullName
if ($inputFiles -eq $NULL -and $outputFiles -eq $NULL) {
Write-Host "Environment is ready for statement processing."
}
else {
Write-Host "Environment is NOT ready for statement processing."
Write-Host "The following files exist in input/output: `n"
$inputFiles
$outputFiles
#Throw "Files exist in input/output. See above for details."
}
}
Below is the console output:
Environment is NOT ready for statement processing.
The following files exist in input/output:
Environment is NOT ready for statement processing.
The following files exist in input/output:
FullName
--------
\\server1.com\C$\jobs\statements\input\asdasd.txt
\\server1.com\C$\jobs\statements\input_254\asdasd.txt
\\server1.com\C$\jobs\statements\input_test\asdasd.txt
\\server2.com\C$\jobs\statements\input\CUSSTAT10302021.245
\\server2.com\C$\jobs\statements\input\CUSSTAT11312021
\\server2.com\C$\jobs\statements\input\CUSSTAT11312021.zip
And below is the console output when I uncomment the "throw" line:
Environment is NOT ready for statement processing.
The following files exist in input/output:
Files exist in input/output. See above for details.
At C:\jobs\statements\bin\Statements-EnvironmentCheck.ps1:47 char:9
+ Throw "Files exist in input/output. See above for details."
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (Files exist in ...ve for details.:String) [], RuntimeException
+ FullyQualifiedErrorId : Files exist in input/output. See above for details.
I know I have some error output cleanup to perform in order to include all the servers that might have files present, but please ignore that for now.
What you're experiencing is explained in this answer and this answer, basically you need to implement Out-Host \ Out-Default:
$inputFiles, $outputFiles | Out-Host # Should fix the problem
# possibly `throw` might require this too
throw "Files exist in input/output. See above for details." | Out-Host
However, I feel is worth showing you a better way to approach your code, returning a unified array of objects which you can filter, sort and export.
$allServers = #(
"server1.com"
"server2.com"
)
$result = foreach ($server in $allServers) {
# use `-File` instead of `! $_.PSIsContainer`
$out = #{
in = Get-ChildItem "\\$server\C$\jobs\statements\input*\" -Recurse -File
out = Get-ChildItem "\\$server\C$\jobs\statements\output*\" -Recurse -File
}
# if $out['in'] and $out['out'] are `$null`, Ready is `$true`
[pscustomobject]#{
Ready = -not($out['in'] -or $out['out'])
Server = $server
Files = $out
}
}
Now, if you want to see which servers are Ready (no files in input and output):
$result.where{ $_.Ready }
And if you want to see which servers are not Ready, and have a list of the files:
$result.where{ -not $_.Ready }.foreach{
foreach($file in $_.Files.PSBase.Values.FullName) {
[pscustomobject]#{
Server = $_.Server
Files = $file
}
}
}
Being new to PowerShell I've been following some of the guidance in these posts to write a script for what's mentioned in the subject.
Here's the script:
Get-Content -Path C:\temp\Domain.txt | Restart-Computer -force | Where-Object { $._Name -notmatch "^(SERVER01)"}
Here's the error:
Restart-Computer : Cannot validate argument on parameter 'ComputerName'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At line:1 char:40
+ ... et-Content -Path C:\temp\Domain.txt | Restart-Computer -force | Where ...
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:PSObject) [Restart-Computer], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RestartComputerCommand
For reference, the DOMAIN.txt has a list of servers that will periodically change so I want to skip certain servers should they end up on the list.
The error simply means you have an empty line on your text file, you can filter the lines using .Where(..) method and exclude empty or white space lines with the help of [string]::IsNullOrWhiteSpace(..) method. I have changed -notmach for the containment operator -notin.
Note, -notin looks for an exact match within the collection $hostsToExclude.
$hostToExclude = 'server1', 'server2'
(Get-Content -Path C:\temp\Domain.txt).Where({
-not [string]::IsNullOrWhiteSpace($_) -and $_ -notin $hostToExclude
}) | Restart-Computer -Force
It's worth noting that, on your snippet, you're restarting the hosts before filtering the collection. Get-Content should be followed by Where-Object.
I am writing a PS Script to try and locate a folder on a remote server. Here is the code:
# Set file to be tested for, put everything after c:\
# “c:\Users\Default” is the example path
$filetofind = "EventLogs"
# Hostnames TXT Location
$hostnamestxt = "C:\Scripts\Powershell_Remote_File_Query\hosts.txt"
# Destination file for Online Machines
$onlinetxt = "C:\Scripts\Powershell_Remote_File_Query\Machines_with_file.txt"
# Destination file for Offline Machines
$offlinetxt = "C:\Scripts\Powershell_Remote_File_Query\Offline_Machines.txt"
##########################################################
# Begin Executing Script – Do Not Edit Below This Line
##########################################################
$computers = get-content “$hostnamestxt”
write-host “———————————————-”
write-host “Scanning hostnames from $hostnamestxt…”
write-host “———————————————-”
foreach($computer in $computers)
{
ping -n 1 $computer >$null
if($lastexitcode -eq 0)
{
if(test-path “\\$computer\c$\$filetofind”)
{
echo “$computer” | Out-File -Append “$onlinetxt”
write-host “File FOUND on $computer”
}
else
{write-host “File NOT found on $computer”}
}
else
{
echo “$computer” | Out-File -Append “$offlinetxt”
write-host “$computer is OFFLINE/DID NOT RESPOND TO PING”
}
}
write-host “———————————————-”
write-host “Script has completed please check output.”
write-host “Hosts with file output location – $onlinetxt”
write-host “Hosts that were unpingable output location – $offlinetxt”
write-host “———————————————-“
I get this error when running the script:
get-content : Cannot find path 'C:\Scripts\Powershell_Remote_File_Query\“€' because it does not exist.
At C:\Scripts\Powershell_Remote_File_Query\Powershell_Remote_File_Query_Script.ps1:24 char:18
+ $computers = get-content “$hostnamestxtâ€
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\Scripts\Powe...ile_Query\“€:String) [Get-Content], ItemNotFoundEx
ception
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand
Both the script itself and the txt file are in the same directory. Please forgive me I'm new to Powershell and not a programmer by any means.
Instead of doing this...
$hostnamestxt = "C:\Scripts\Powershell_Remote_File_Query\hosts.txt"
$computers = get-content “$hostnamestxt”
Try just doing this...
$computers = get-content "C:\Scripts\Powershell_Remote_File_Query\hosts.txt"
I understand what you are trying to do should result to the same thing, yet, let's just try to eliminate that extra thing, and give it a shot to see if you get a different result.
Also, if that file you are reading is on a remote host, then you should be using the UNC file share path, not your local C: drive. Just assuming a bit here.
In the script attached I am trying to rename a PC if the PC has a certain hostname. However, the script is proceeding anyway and bypasses the if/else statement.
What am I doing wrong? I am kind of new with Windows Powershell.
Thanks!
# get current computername
$hostname = hostname.exe
#$env:computername
If ( $hostname = "CLNT3100" )
{
#Get all the computers with CLNT3* and sort them with the 'highest client' on top. Then put them in newlist.txt
Get-ADComputer -Filter 'SamAccountName -like "CLNT3*"' | Select -Exp Name | Sort-Object -Descending >> C:\newlist.txt
#Put the text file in a variable and show the top line
$Text = Get-Content -Path C:\newlist.txt
#$Text[0]
#Trim CLNT for numbering
$Text1 = $Text[0].TrimStart("CLNT")
#Add 1 number to the previous CLNT
$Text2 = 1 + $Text1
#Add CLNT again to the new variable
$Text3 = "CLNT" + $Text2
#Rename the computer
Rename-Computer –computername minint –newname $Text3
}
Else
{
Write-Host "Computernaam is niet minint!!!"
}
To compare if two values are equal in Powershell you have to use the -eqoperator.
Check the Powershell equality operators to see the others like -gt, -lt etc, or type man about_Comparison_Operators in the PS shell.
Also, to learn Powershell I found this free ebook to be very good.
I'm trying to create a mount point using Powershell. it's done locally, and here is the code & issue i'm having.
$choice = "t"
New-Item -ItemType directory -Path "E:\Data\Riptide\Ariis\Ris\Docs\interPrimary1\"
$orgdrive = "E:\Data\Riptide\Ariis\Ris\Docs\interPrimary1\"
$driveLetter= $Choice + ":\"
$driveinfo=get-wmiobject win32_volume | where { $_.driveletter -eq $choice + ":" } | select-object DeviceID
Mountvol $orgdrive $driveinfo
When executed, I get that the parameter is incorrect.
Thanks in advance.
You just have to try :
mountvol $orgdrive $driveinfo.DeviceID
For the future you can test :
$driveinfo| Get-Member
You can find here a tool that allow you to test the command line parameters.