I have to query my Outlook Add-ins and check if two specific ones are installed.
This is what I have:
$searchScopes = "HKCU:\SOFTWARE\Microsoft\Office\Outlook\Addins","HKLM:\SOFTWARE\Wow6432Node\Microsoft\Office\Outlook\Addins"
$searchScopes | % {Get-ChildItem -Path $_ | % {Get-ItemProperty -Path $_.PSPath} | Select-Object #{n="Name";e={Split-Path $_.PSPath -leaf}},FriendlyName,Description} | Sort-Object -Unique -Property name
This shows me all installed Add-ins. Now I dont know how to filter the result to get a true or false.
Like the following
If List contains 'addin1' then 'addin1' installed = true
Do you have a list of addins to check if they are installed? What do you want to do once you have found that something is installed or not?
You could make use of the -in operator, which checks a value against a list and is true if the value is in the list. All this code does is print to host; the logic in the loop will need to be changed to match your requirements.
$searchScopes = "HKCU:\SOFTWARE\Microsoft\Office\Outlook\Addins","HKLM:\SOFTWARE\Wow6432Node\Microsoft\Office\Outlook\Addins"
$names = $searchScopes | % {Get-ChildItem -Path $_ | % {Get-ItemProperty -Path $_.PSPath} | Select-Object #{n="Name";e={Split-Path $_.PSPath -leaf}},FriendlyName,Description} | Sort-Object -Unique -Property name
if("addin1" -in $names){
Write-Host "addin1 is installed."
}
Using your code, add the second line into a variable
$searchScopes = "HKCU:\SOFTWARE\Microsoft\Office\Outlook\Addins","HKLM:\SOFTWARE\Wow6432Node\Microsoft\Office\Outlook\Addins"
$Results = $searchScopes | % {Get-ChildItem -Path $_ | % {Get-ItemProperty -Path $_.PSPath} | Select-Object #{n="Name";e={Split-Path $_.PSPath -leaf}},FriendlyName,Description} | Sort-Object -Unique -Property name
then query the results:
$Results.Name -contains 'TeamViewerMeetingAddIn.AddIn'
or
$Results.FriendlyName -match 'Google Apps'
To filter:
$Results | ? {$_.Name -contains 'TeamViewerMeetingAddIn.AddIn'}
Related
I'm new to PS scripting (really, I started today) and, for a project, I need to create a .txt file with all the extensions from all shared folders on the local machine (a Windows file server).
I think I'm on the right path with this :
get-childitem -Path C:\test -Recurse | select extension -unique > $PSScriptRoot\ExtensionList.txt
It's doing exactly what I want for a given path and all subfolders but now I need to apply this to all shared folders on the machine.
I was able to list all the shared folder's path with this command :
$Shares= #(Get-WmiObject Win32_Share |
Select Name,Path,Type |
Where-Object { $_.Type -match '0|2147483648' } |
Select -ExpandProperty Path |
Select -Unique)
Write-Host $Shares
Now I'm stuck, I suppose I need to use the foreach command but I can't find the way to make it work.
Can someone help me put this together ?
Thanks,
You can try Get-SMBShare cmdLet:
Get-SMBShare | Foreach {
Get-ChildItem "\\$($_.name)" | Select-Object Extension -Unique
}
You're probably looking for something similar to this:
$Shares = #( Get-CimInstance Win32_Share | Where-Object { $_.Type -match '0|2147483648' } | Select -Unique )
ForEach ( $Share In $Shares ) { Get-ChildItem -Path $Share.Path -File -Recurse -ErrorAction Ignore | Select -Unique -ExpandProperty Extension }
I'll leave you to split the lines to match your particular style and to output to a file, (I'd advise that you consider using Out-File instead of > for that).
Thank you guys for your help! I was able to figure it out.
The following script will gather all extensions on shared folders, sort them, eliminate duplicates and empty lines, add "*' before the extension and create a file list.txt with the result.
#get shares
$Shares = #( Get-CimInstance Win32_Share |
Where-Object { $_.Type -match '0|2147483648' } |
Select -Unique )
#list all extensions
ForEach ( $Share In $Shares ) { Get-ChildItem -Path $Share.Path -File -Recurse -ErrorAction Ignore | Select -Unique -ExpandProperty Extension | out-file C:\extensions\List1.txt -append }
#remove empty lines
#(gc C:\extensions\List1.txt) -match '\S' | out-file C:\extensions\List2.txt
#Add * before extention type
gc C:\extensions\List2.txt | %{"*$_"} | out-file C:\extensions\List3.txt
#Sort by name
gc C:\extensions\List3.txt | sort | get-unique > C:\extensions\List4.txt
#Remove duplicates
$hash = #{}
gc C:\extensions\List4.txt |
%{if($hash.$_ -eq $null) { $_ }; $hash.$_ = 1} > C:\extensions\List.txt
#Delete list1-4
Remove-Item C:\extensions\List1.txt, C:\extensions\List2.txt, C:\extensions\List3.txt, C:\extensions\List4.txt
I have a collection of type Microsoft.Win32.RegistryKey Example:
$arr = Get-ChildItem HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
The 3rd element contains the property I am interested in. I access it using:
$arr[3] | Get-ItemProperty | Where-Object {$_.DisplayName -like "MyProgram*"}
This works fine. Now I am trying to loop over the collection (index number is not known):
$arr | ForEach-Object { Get-ItemProperty $_ | Where-Object {$_.DisplayNAme -like "MyProgram*"}
Returns the error: "Cannot find path because it does not exist".
How can I display the same output as $arr[3] | ... using a loop?
What am I doing wrong?
Did you try to search for it?
Get-ItemProperty -Path REGISTRY::HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* |
Where-Object {$_.Displayname -like 'MyProgram*'}
I have a script that filters my logs, but the problem is that when I would like to delete everything else but certain files I get errors of Unrecognized escape sequence. I've been trying to split the values but it seems that nothing works. I also tried -exclude before, but didn't get it to work. It's supposed to remove all the other files but $result and $clr.
$files = #()
[xml]$photonconfig = Get-Content C:\Users\Administrator\Desktop\PhotonServer.config
$photonconfig.SelectNodes("Configuration/*") | Select-Object -Expand Name | % {
$_.Replace("xxx","")
} | ForEach {
$files+= Get-ChildItem C:\Users\Administrator\Desktop\log\log/*$_*.log |
sort -Property LastWriteTime -Descending |
Select-Object -First 3
}
$result = $files | Sort-Object LastAccessTime -Descending |
Select-Object -First 3
$clr = "PhotonCLR.log"
$all = Get-ChildItem C:\Users\Administrator\Desktop\log\log/* |
Where-Object { $_.Name -notmatch $result } |
Remove-Item
The second operand of the -match and -notmatch operators is a regular expression, not an array of file names. Use the -contains operator instead:
... | Where-Object { $result -notcontains $_.Name } | ...
On PowerShell v3 and newer you can also use the -notin operator, which feels a little more "natural" to most people:
... | Where-Object { $_.Name -notin $result } | ...
Note that for this to work you also need to expand the Name property when building $result:
$result = $files | Sort-Object LastAccessTime -Descending |
Select-Object -First 3 -Expand Name
I have a script that reports NTDS service status from entire forest there are few 2003 servers which I want exclude below is the script.
$getForest = [system.directoryservices.activedirectory.Forest]::GetCurrentForest()
$getForest.domains | ForEach-Object {$_.DomainControllers} | ForEach-Object {$_.Name}
I was trying something like
$getForest = [system.directoryservices.activedirectory.Forest]::GetCurrentForest()
$getForest.domains | ForEach-Object {$_.DomainControllers} | ForEach-Object {$_.Name} | where-object {$_.name -notlike "server2003.domain.local"}
No luck
Your second ForEach-Object isn't needed, so I've consolidated it into the first.
For this kind of thing I would recommend creating an array of names you want excluded, which I called $exclude.
Then I'm using the -notcontains operator to check the name against the list from within Where-Object.
$exclude = #(
'server2003.domain.local'
'other2003.domain.local'
)
$getForest = [system.directoryservices.activedirectory.Forest]::GetCurrentForest()
$getForest.domains |
ForEach-Object {$_.DomainControllers.Name} |
Where-Object {$exclude -notcontains $_.name}
I got it working
$exclude = #(
'dc2.local'
'dc3.local'
'dc4.local'
'dc5.local'
)
(Get-ADForest).Domains | %{ Get-ADDomainController -Filter * -Server $_ } | Where-Object {$exclude -notcontains $_.hostname} | select Hostname
I have logs that are getting written from various Linux servers to a central windows NAS server. They're in E:\log in the format:
E:\log\process1\log20140901.txt,
E:\log\process2\20140901.txt,
E:\log\process3\log-process-20140901.txt,
etc.
Multiple files get copied on a weekly basis at the same time, so created date isn't a good way to determine what the newest file is. Therefore I wrote a powershell function to parse the date out, and I'm attempting to iterate through and get the newest file in each folder, using the output of my function as the "date". I'm definitely doing something wrong.
Here's the Powershell I've written so far:
Function ReturnDate ($file)
{
$f = $file
$f = [RegEx]::Matches($f,"(\d{8})") | Select-Object -ExpandProperty Value
$sqlDate = $f.Substring(0,4) + "-" + $f.substring(4,2) + "-" + $f.substring(6,2)
return $sqlDate
}
Get-ChildItem E:\log\* |
Where {$_.PsIsContainer} |
foreach-object { Get-ChildItem $_ -Recurse |
Where {!$_.PsIsContainer} |
ForEach-Object { ReturnDate $_}|
Sort-Object ReturnDate -Descending |
Select-Object -First 1 | Select Name,ReturnDate
}
I seem to be confounding properties and causing "You cannot call a method on null-valued expression errors", but I'm uncertain what to do from here.
I suspect your $f variable is null and you're trying to invoke a method (Substring) on a null value. Try this instead:
Get-ChildItem E:\Log -File -Recurse | Where Name -Match '(\d{8})\.' |
Foreach {Add-Member -Inp $_ NoteProperty ReturnDate ($matches[1]) -PassThru} |
Group DirectoryName |
Foreach {$_.Group | Sort ReturnDate -Desc | Select -First 1}
This does require V3 or higher. If you're on V1 or V2 change it to this:
Get-ChildItem E:\Log -Recurse |
Where {!$_.PSIsContainer -and $_.Name -Match '(\d{8})\.'} |
Foreach {Add-Member -Inp $_ NoteProperty ReturnDate ($matches[1]) -PassThru} |
Group DirectoryName |
Foreach {$_.Group | Sort ReturnDate -Desc | Select -First 1}
Your code was ok for me when i tried it up until you did a select you were requesting name and returndate when those properties did not exist. Creating a custom object with those values would make your code work. Also i removed some of the logic from your pipes. End result should still work though (I just made some dummy files to test with like your examples).
Working with your original code you could have something like this. This would only work on v3 or higher. Simple changes could make it work on lower if need be. Mostly where [pscustomobject] is concerned.
Function ReturnDate ($file)
{
$f = $file
$f = [RegEx]::Matches($f,"(\d{8})") | Select-Object -ExpandProperty Value
$sqlDate = $f.Substring(0,4) + "-" + $f.substring(4,2) + "-" + $f.substring(6,2)
[pscustomobject] #{
'Name' = $file.FullName
'ReturnDate' = $sqlDate
}
}
Get-ChildItem C:\temp\E\* -Recurse |
Where-Object {!$_PSIsContainer} |
ForEach-Object{ReturnDate $_} |
Sort-Object ReturnDate -Descending |
Select-Object -First 1
The Sort-Object cmdlet supports sorting by a custom script block and will sort by whatever the script block returns. So, use a regular expression to grab the timestamp and return it.
Get-ChildItem E:\log\* -Directory |
ForEach-Object {
Get-ChildItem $_ -Recurse -File |
Sort-Object -Property {
if( $_.Name -match '(\d{8})' )
{
return $Matches[1]
}
Write-Error ('File ''{0}'' doesn't contain a timestamp in its name.' -f $_.FullName)
} |
Select-Object -Last 1 |
Select Name,ReturnDate
}
Note that Select-Object -First 1 was changed to Select-Object -Last 1, since dates would be sorted from oldest to newest.