I came across PowerShell script to log Microsoft Office version of remote computer on domain. I want to run it as logon script to I modified OpenRemoteBaseKey to OpenBaseKey and this is the code:
$version = 0
$reg = [Microsoft.Win32.RegistryKey]::OpenBaseKey('LocalMachine', 'Default')
$reg.OpenSubKey('software\Microsoft\Office').GetSubKeyNames() |% {
if ($_ -match '(\d+)\.') {
if ([int]$matches[1] -gt $version) {
$version = $matches[1]
}
}
}
if ($version) {
Add-Content -Path \\server\share\oversion.txt -Value "$env:computername $env:username : $version"
}
else {
Add-Content -Path \\server\share\oversion.txt -Value "$env:computername $env:username : 0"
}
but now I receive error:
You cannot call a method on a null-valued expression.
At line:4 char:1
+ $reg.OpenSubKey('software\Microsoft\Office').GetSubKeyNames() |% {
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
but not sure what this means since GetSubKeyNames seems valid: https://learn.microsoft.com/en-us/dotnet/api/microsoft.win32.registrykey.getsubkeynames?view=netframework-4.7.2, also it works with OpenRemoteBaseKey, can someone point me to right direction, please?
I'm not sure why OpenRemoteBaseKey works, but OpenBaseKey doesn't because I cannot reproduce that..
You might however try the more Powershell way of doing this:
$version = 0
Get-ChildItem -Path 'HKLM:\SOFTWARE\Microsoft\Office' -Name | Where-Object {$_ -match '(\d+)\.\d+'} | ForEach-Object {
$version = [math]::Max([int]$_, $version)
}
Add-Content -Path \\server\share\oversion.txt -Value "$env:COMPUTERNAME $env:USERNAME : $version"
Related
I have a powershell script to delete a folder on a bunch of Windows hosts in our cluster.
It runs fine in the ISE and when running local from my laptop. however, I installed powershell on my Centos7.2 machine and when I try to run I get the following error
Join-Path : Cannot process argument because the value of argument "drive" is
null. Change the value of argument "drive" to a non-null value.
At /home/user/powershell/delete_.file.ps1:11 char:20
+ $newfilepath = Join-Path "\\$computer" "$file"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Join-Path],
PSArgumentNullException
+ FullyQualifiedErrorId :
ArgumentNull,Microsoft.PowerShell.Commands.JoinPathCommand
Test-Path : Cannot bind argument to parameter 'Path' because it is null.
At /home/user/powershell/delete_.file.ps1:12 char:19
+ if (test-path $newfilepath) {
+ ~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Test-Path],
ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.TestPathCommand
here is the code to the script
$filelist = #("C$\.file")
$computers = Get-Content /home/user/powershell/sw_win.txt
foreach ($file in $filelist)
{
foreach ($computer in $computers)
{
Write-Host -ForegroundColor Yellow "Analysing $computers"
$newfilepath = Join-Path "\\$computer" "$file"
if (test-path $newfilepath) {
Write-Host "$newfilepath Folder exists"
try
{
Remove-Item $newfilepath -Force -recurse -ErrorAction Stop
}
catch
{
Write-host "Error while deleting $newfilepath on $computer.
`n$($Error[0].Exception.Message)"
}
Write-Host "$newfilepath folder deleted"
} else {
Write-Information -MessageData "Path $newfilepath does not exist"
}
}
}
I think its because $computer is not set, but what doesn't make sense is it works fine using ISE.
Any help would be appreciated
I am trying to get the .Net version from the system and trying to check does my system have .Net version greater than or equal to 4.6 or not. Below is the code. From the code I am able to retrieve the release version. I am facing a problem in the if condition.
$myArray = #()
$myArray = #(Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse |
Get-ItemProperty -Name Release,Release -EA 0 |
Where { $_.PSChildName -match '^(?!S)\p{L}' } |
Select Release)
Write-Output $myArray[0]
Write-Output $myArray[1]
$var1 = 393295
foreach ($var in $myArray) {
Write-Output $var
if ($var -ge $var1) {
Write-Output same
} else {
Write-Output NOT same
}
}
I am getting this error:
Cannot compare "#{Release=461808}" to "393295" because the objects are not the
same type or the object "#{Release=461808}" does not implement "IComparable".
At C:\Users\Desktop\DotNet.ps1:13 char:9
+ if ($var -ge $var1) {
+ ~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], ExtendedTypeSystemException
+ FullyQualifiedErrorId : PSObjectCompareTo
Change the foreach line as
foreach($var in $myArray.Release)
After trying a number of approaches, including what seemed an excellent suggestion at http://www.bdevuyst.com/powershell-path-msbuild-exe/, which gave me an error, I tried to break it down. Though I get the latest MSBuild registry key (14.0), I still get this error when I try to extract the path to MSBuild:
Get-ItemProperty : Cannot find path 'C:\USERS\user\Desktop\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\MSBuild\ToolsVersions\14.0' because it does not exist.
At C:\USERS\mtroi\Desktop\VSS_POC1_Setup.ps1:529 char:5
+ Get-ItemProperty -Path $MsBuildVersion -Name MSBuildToolsPath
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\USERS\mtroi\...lsVersions\14.0:String) [Get-ItemProperty], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetItemPropertyCommand
# 32bit or 64bit local OS?
if($ENV:PROCESSOR_ARCHITECTURE -eq "x86")
{$HKLMpath = "HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions\"}
elseif($ENV:PROCESSOR_ARCHITECTURE -eq "AMD64")
{$HKLMpath = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\MSBuild\ToolsVersions\"}
else
{Write-Host "Local processor architecture not supported. Exiting installation..."; EXIT}
# Which path (version) of local MSBuild?
$_decSep = [System.Threading.Thread]::CurrentThread.CurrentUICulture.NumberFormat.CurrencyDecimalSeparator;
$MsBuild1 = #(Get-ChildItem -Path $HKLMpath | Where { $_.Name -match '\\\d+.\d+$' })
ForEach ($build in $MsBuild1)
{
$Expression=$Expression+","+[System.Convert]::ToDecimal($build.Name.Substring($build.Name.LastIndexOf("\") + 1))
}
$MsBuildVersion = Get-ChildItem -Path $HKLMpath | Where { $_.Name -match '\\\d+.\d+$' } |
Sort-Object -Property #{Expression=$Expression} -Descending |
Select-Object -First 1 #| Get-ItemProperty -Name MSBuildToolsPath
Get-ItemProperty -Path $MsBuildVersion -Name MSBuildToolsPath
This question already has answers here:
A parameter cannot be found that matches parameter name 'directory'
(2 answers)
Closed last year.
I am getting Get-ChildItem : *A parameter cannot be found that matches parameter name 'Directory'* error message , below is the script used, kindly help me in finding the issue?
Script:
Function Clear-ReadOnlyFiles([string]$path)
{
"Clearing readonly attribute from files in $path"
New-Variable -Name read_only -Value 1 -Option readonly
Get-ChildItem -Path $path |
Where-Object { $_.attributes -match 'readonly' } |
ForEach-Object {
$_.attributes = $_.attributes -Bxor $read_only }
}#end Clear-ReadonlyFiles
$ZipCmd = "{0}\7za.exe" -f $BackupDir
$ZipCmdArgs = "-sdel"
# Grab Directories in Location
$Directories = Get-ChildItem -Path $BackupDir -Directory
# Cycle Through and Launch 7za to Compress
# Check if Archive Exists - If yes, delete source folder
ForEach ($Directory in $Directories)
{
$Source = "{0}\{1}" -f $BackupDir,$Directory.Name
$Archive = "{0}.7z" -f $Source
# Clear Read-Only Attribute on Folder
$SubFiles = Get-ChildItem -Path $Directory -Recurse -ReadOnly
ForEach ($SubFile in $SubFiles) {
$SubFile.IsReadOnly = $False
}
#If ($Directory.IsReadOnly -eq $True) { $Directory.set_IsReadOnly($False) }
$AllArgs = #('a', $ZipCmdArgs, $Archive, $Source);
& $ZipCmd $AllArgs
}
Error message:
Get-ChildItem : A parameter cannot be found that matches parameter name 'Directory'.
At C:\Play\BackupCompress.ps1:35 char:57
+ $Directories = Get-ChildItem -Path $BackupDir -Directory <<<<
+ CategoryInfo : InvalidArgument: (:) [Get-ChildItem], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
Get-ChildItem : A parameter cannot be found that matches parameter name 'ReadOnly'.
At C:\Play\BackupCompress.ps1:45 char:66
+ $SubFiles = Get-ChildItem -Path $Directory -Recurse -ReadOnly <<<<
+ CategoryInfo : InvalidArgument: (:) [Get-ChildItem], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
Property 'IsReadOnly' cannot be found on this object; make sure it exists and is settable.
At C:\Play\BackupCompress.ps1:47 char:18
+ $SubFile. <<<< IsReadOnly = $False
+ CategoryInfo : InvalidOperation: (IsReadOnly:String) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound
I believe that the Directory switch was added in PowerShell 3.0. In older versions you will need to check the PSIsContainer property of each child item, which will be true if the item is a directory:
$Directories = Get-ChildItem -Path $BackupDir | Where-Object { $_.PSIsContainer }
-Directory is a conditional parameter and only works on paths whose provider is "FileSystem". It's present on this page: Get-ChildItem for FileSystem, but not on the generic one.
Make sure that the correct provider appears when you type the following:
Get-Item $BackupDir | Select-Object -Property PSProvider
Where am I going wrong with the below script...it checks for if files are of zero (0) bytes and then if they are it moves them to a folder.
It works fine outside of the IF statement but when I try it in the below it fails copying the files and displays the below error:
Move-Item : Cannot bind argument to parameter 'Path' because it is
null. At C:\Tools\jon\testing_scheduled.ps1:109 char:11
+ Move-Item <<<< $moving "$scheduledpath\Move_empty"
+ CategoryInfo : InvalidData: (:) [Move-Item], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.MoveItemCommand
filter gettheheckout([string]$path = '.')
{
$move = Get-ChildItem $scheduledpath | Where-Object {$_.length -eq 0} | Foreach-Object {$_.fullName}
}
$moving = gettheheckout
$check = #(Get-ChildItem $scheduledpath | Where-Object {$_.length -eq 0})
if ($check.length -eq 0)
{
Write-host = "No files to move - Script Completed" -ForegroundColor Cyan
}
else
{
Move-Item $moving "$scheduledpath\Move_empty"
Write-Host "Script Completed - Use Excel to Filter on commas - Have a nice day!" -ForegroundColor Cyan
}
change this:
filter gettheheckout([string]$path = '.')
{
Get-ChildItem $scheduledpath | Where-Object {$_.length -eq 0} | Foreach-Object {$_.fullName}
}
and be sure $scheduledpath is a global scope variable and have a value.