OK, here are the scripts that I created.  I am new to PowerShell and I used 
these scripts to learn PowerShell so keep that in mind as you review and use 
these.  All I ask is that you review them and let me know if there is anything 
that should be changed.

The first script that I run is the Count_Bad_Inventory_Files.ps1  I follow that 
with ProcessSMS_InBox_HardwareInv.ps1.  I usually keep a running log file so I 
can see if I get any machines with repeatedly bad mif files.  I then run the 
Repeat_Bad_Hareware_Inventory.ps1 script to process the log file.

The forth script I run stand-alone (not is sequence with the above scripts) 
just to see what machines are generating bad mif files.

Enjoy…

Thanks,
Ken …

From: [email protected] [mailto:[email protected]] On 
Behalf Of Lutz, Ken
Sent: Tuesday, August 13, 2013 8:04 AM
To: [email protected]
Subject: RE: [mssms] BADMIFS - dataldr.box

Sure, just let me add a few comments and clean them up a little.  I’ll post 
them later this morning.

Thanks,
Ken …

From: [email protected]<mailto:[email protected]> 
[mailto:[email protected]] On Behalf Of Gary Ossewaarde
Sent: Tuesday, August 13, 2013 7:03 AM
To: [email protected]<mailto:[email protected]>
Subject: RE: [mssms] BADMIFS - dataldr.box

Any interest in sharing any or all parts of said script? I’m just getting into 
CM12 and have found some bad mifs that I’d like to check into.

Gary

From: [email protected]<mailto:[email protected]> 
[mailto:[email protected]] On Behalf Of Lutz, Ken
Sent: Tuesday, August 13, 2013 9:52 AM
To: [email protected]<mailto:[email protected]>
Subject: RE: [mssms] BADMIFS - dataldr.box

Hi Sherry,

That’s what I have done.  I created a PowerShell script to walk through the bad 
mif folders and send a full inventory command to the offending machines.

Thanks,
Ken …

From: [email protected]<mailto:[email protected]> 
[mailto:[email protected]] On Behalf Of Sherry Kissinger
Sent: Monday, August 12, 2013 6:04 PM
To: [email protected]<mailto:[email protected]>
Subject: Re: [mssms] BADMIFS - dataldr.box

Yes, I'd start with forcing a full hinv to clean up hopefully most of them
"Lutz, Ken" <[email protected]<mailto:[email protected]>> wrote:
I have a question about BADMIFS in the dataldr.box folder.  I have been 
monitoring this for a few days now and have 154 bad mifs since 08-05-13.  Most 
of them (111) are in the NonExistentRow folder.  What is the best way to deal 
with these bad mifs?  Would a good starting point be to force a full hardware 
inventory on the offending machines?  I’m looking into the inventoryagent.log 
files now, but not seeing anything that stands out.


[content://com.fsck.k9.attachmentprovider/b6ae8a1e-bc1a-4c90-ab1e-3a5a0dcc0286/8188/RAW]
Ken Lutz
Senior Systems Administrator
Information Systems Department
Spokane County
815 N. Jefferson
Spokane, Washington  99260










######################################
## Computers-Bad_Inventory.ps1
## by Ken LUtz (Spokane County)
## August 1, 2013
######################################
<#
.SYNOPSIS
Read in each bad Hardware Inventory mif file and each bad Software Inventory 
sid file and pars the file to get a list
of unique computer names.

Be sure the change the siteserver to your site server name.

.EXAMPLE
PS > .\Computers-Bad_Inventory.ps1

#>

$INBoxPath = "\\<SiteServer>\SMS_SMS\inboxes\sinv.box\badsinv"
$FullMifPath = Get-ChildItem -path $InBoxPath -recurse -filter *.sid | select 
FullName
$CMPLength = 62  # = starting location of the computer name in the SID file.

Write-Host "Repeat offenders - Both inventory types..."
#If there aren't any bad SID files exit now.
$BadSIDS = Get-ChildItem -path $InBoxPath -recurse -filter *.sid | select 
FullName | Measure-Object
if($BadSIDS.count -eq 0)
    {
     Write-Host "No Software SID files..." -ForegroundColor DarkRed
        }
        Else
        {
                #   Get the computer name from each of the SID files.
                $ComputerNameSW= @()
                $Data = $FullMifPath | % {Get-Content $_.FullName 
|Select-Object -First 1}
                Foreach($Line in $Data)
                {
                        $idx = $Line.IndexOf(0x0,$CMPLength)
                        $ComputerNameSW += $Line.Substring($CMPLength, $idx - 
$CMPLength)    
                }
                $ComputerNameSW = $ComputerNameSW | Select -Unique | 
Sort-Object 
                $CompCntSW = $ComputerNameSW | Measure-Object
                $CompCntSW = $CompCntSW.count
                Write-Host "Unique Computers with Bad Software Inventory = 
$CompCntSW"
                foreach($NameSW in $ComputerNameSW)
                        {
                        Write-Host $NameSW -ForegroundColor DarkGray
                        }
        }   

# Now check for bad Harware Inventory...
$INBoxPath = "\\<SiteServer>\SMS_SMS\inboxes\auth\dataldr.box\BADMIFS"
$BadMifs = Get-ChildItem -path $InBoxPath -recurse -filter *.mif | select 
FullName | Measure-Object
$CountBadMifs = [string]$BadMifs.Count
$FullMifPath = Get-ChildItem -path $InBoxPath -recurse -filter *.mif | select 
FullName
$Reg = [RegEx] '<NetBIOS Name><(.+)>'
$ComputerNamesHW = $FullMifPath | % {Get-Content $_.FullName} | % 
{$Reg.matches($_)} | % {$_.Groups[1].Value}
$UniqComputerNames = $ComputerNamesHW | select -uniq | Sort-Object

If ($CountBadMifs -eq 0)
        {
                Write-Host "No Hardware MIF files..." -ForegroundColor DarkRed
        }
        else
        {
                $CompCntHW = $UniqComputerNames | Measure-Object
                $CompCntHW = $CompCntHW.count
                Write-Host "Unique Computers with Bad Hardware Inventory = 
$CompCntHW"
                foreach($NameHW in $UniqComputerNames)
                {
                        Write-Host $NameHW -ForegroundColor DarkGreen
                }
        }          
######################################
## Count_Bad_Inventory_Files.ps1
## by Ken LUtz (Spokane County)
## August 1, 2013
######################################
<#
.SYNOPSIS
Count the number of bad Hardware Inventory files (mifs) and Software Inventory 
files (sids).

Be sure the change the siteserver to your site server name.

.EXAMPLE
PS > .\Count_Bad_Inventory_Files.ps1

#>


Write-Host " `n"
Write-Host "Count Bad Hardware/Software Inventory Files."

# - Hardware inventory MIF files...
$INBoxPath = "\\<SiteServer>\SMS_SMS\Inboxes\auth\dataldr.box\Badmifs"
Write-Host " `n"
$BadMifs = Get-ChildItem -path $InBoxPath -recurse -filter *.mif | select 
FullName | Measure-Object
Write-Host "Total number of bad (Hardware) MIF files: "$BadMifs.count
Write-Host " "
Write-Host "Folder location with count of bad Hardware Inventory MIF files."
$fso = New-Object -com "Scripting.FileSystemObject"
 $f = $fso.GetFolder($INBoxPath)
 foreach ($folder in $f.subfolders){
    Write-Host $folder.Path '=' $((get-childitem $folder.path).count)
}

Write-Host " `n"

# - Software inventory SID files...
$INBoxPath = "\\<SiteServer>\SMS_SMS\inboxes\sinv.box\badsinv"
$BadMifs = Get-ChildItem -path $InBoxPath -recurse -filter *.sid | select 
FullName | Measure-Object
Write-Host "Number of bad (Software) SID files: "$BadMifs.count

######################################
## ProcessSMS_InBox_HardwareInv.ps1
## by Ken LUtz (Spokane County)
## August 1, 2013
######################################
<#
.SYNOPSIS
Use this script to process the bad hardware inventory mif files found on the 
SMS site server.
This script will:
   1) Parse out the computer name from the bad mif files.
   2) Use WMI to connect to the machine.
      2.A) Issue a full Hardware Inventory command to the machine.
      2.B) Record in log file errors connecting to WMI on said machine.
   3) Delete the bad mif files.

A running log file is kept which can than be used as input to the 
Repeat_Bad_Hardware_Inventory.PS1 script to show what machines have 
had multiple bad inventory issues.  You will be asked to create a new log file 
for each run.  I recommend that you keep a running log file so you 
can find repeat offenders.

--> Be sure the change the siteserver to your site server name.  -- $InBoxPath
--> Change the path used for the output log file -- $OutPath

.EXAMPLE
PS > .\ProcessSMS_InBox_HardwareInv.ps1

#>

# Set variable values now...
# Set the location of the output log file.
$OutPath = 
'\\<SiteServer>\SMSSource\ConfigMgr2012\Scripts\InventorySent_Hardware.log'
$D_T = Get-Date  # get starting date and time.
# Set the location of the bad mif files ...
$INBoxPath = "\\<SiteServer>\SMS_SMS\inboxes\auth\dataldr.box\BADMIFS"
$Counter=0   # count machines processed.

# Do you want to delete the existing InventorySent.log file?
If(Test-Path ($OutPath))
{
Remove-item $OutPath -force -Confirm
}

$FullMifPath = Get-ChildItem -path $InBoxPath -recurse -filter *.mif | select 
FullName

$Reg = [RegEx] '<NetBIOS Name><(.+)>'

$ComputerNames = $FullMifPath | % {Get-Content $_.FullName} | % 
{$Reg.matches($_)} | % {$_.Groups[1].Value}
$CntComputerNames = [string]$ComputerNames.Count
$UniqComputerNames = $ComputerNames | select -uniq
$CntUniqComputerNames = [string]$UniqComputerNames.Count

$LogString = "Start processing Bad DataLdr Mifs   -  $D_T"
Out-File -filepath $OutPath -inputobject $LogString -append

# How many bad MIF files are there?
$BadMifs = Get-ChildItem -path $InBoxPath -recurse -filter *.mif | select 
FullName | Measure-Object
$CountBadMifs = [string]$BadMifs.Count
$LogString = "There are: $CountBadMifs bad MIF files that will be processed.   
-   $D_T"
Out-File -filepath $OutPath -inputobject $LogString -append
Write-Host $LogString
$LogString = "There are $CntUniqComputerNames unique computers out of 
$CntComputerNames total computers to process."
Out-File -filepath $OutPath -inputobject $LogString -append
Write-Host $LogString



#If there aren't any bad MIF files exit now.
if($BadMifs.count -eq 0)
    {
     $LogString = "There are no bad MIF files.   -   $D_T"
         Exit
    }

ForEach($Computer in $UniqComputerNames)

{ # Start ScriptBlock - ForEach
  $Counter = $Counter+1
  Write-Host "Processing machine #: $Counter of $CntUniqComputerNames  -- 
$Computer"
  $LogString4 = "Processing machine #: $Counter of $CntUniqComputerNames  -- 
$Computer"
  Out-File -filepath $OutPath -inputobject $LogString4 -append
  if(!(Test-Connection -ComputerName $Computer -quiet))
  { # Start if for Test-Connection
     $D_T = Get-Date #get current date and time for each pass
     $LogString = "$Computer   -  $D_T   -  Ping Failed - Inventory not reset"
     Out-File -filepath $OutPath -inputobject $LogString -append
      $LogString | Write-warning 
  } # End of $False Test-Connection ScriptBlock
  Else
  { # Start of $True Test-Conneciton ScriptBlock
       $D_T = Get-Date #get current date and time for each pass
       $LogString2 = "   $Computer - Hardware Inventory processed."
       $Error.Clear()
       # Remove current Software Inventory task, then recreate new task to 
force full inventory
       # Check to see if there were any errors connecting to WMI...
       
[wmi]"\\$Computer\ROOT\ccm\invagt:InventoryActionStatus.InventoryActionID='{00000000-0000-0000-0000-000000000001}'"
 | remove-wmiobject
       $ErrorCode = $Error[0].Exception
       switch -regex ($ErrorCode) {
       ("The RPC server is unavailable") 
       {
       Write-warning "RPC Unavailable on $computer."
       $LogString = "** - RPC Unavailable on $computer   -  $D_T"
       Out-File -filepath $OutPath -inputobject $LogString -append
       continue
       }
       ("Access denied") 
       { 
       Write-warning "Access Denied on $computer."
       $LogString = "** - Access Denied on $computer   -  $D_T"
       Out-File -filepath $OutPath -inputobject $LogString -append
       continue
       }
       ("Access is denied") 
       {
       Write-warning "Access is Denied on $computer."
       $LogString = "** - Access is Denied on $computer   -  $D_T"
       Out-File -filepath $OutPath -inputobject $LogString -append
       continue
       }
       ("Invalid Object") 
       {
       Write-warning "No Hardware Inventory item to remove on $computer."
       $LogString = "** - No Hardware Inventory item to remove on $computer   - 
 $D_T"
       Out-File -filepath $OutPath -inputobject $LogString -append
       continue
       }
       ("Insufficient memory") 
       {
       Write-warning "Insufficient memory on $computer."
       $LogString = "** - Insufficient memory on $computer   -  $D_T"
       Out-File -filepath $OutPath -inputobject $LogString -append
       continue
       }
       }
       
([wmiclass]"\\$Computer\Root\CCM:SMS_Client").TriggerSchedule('{00000000-0000-0000-0000-000000000001}')
       Out-File -filepath $OutPath -inputobject $LogString2 -append
   } # End if for Test-connetion

} # End ScriptBlock - ForEach

$FullMifPath | % {Remove-Item -Path $_.FullName -Force}
$LogString = "Finished deleting Bad DataLdr Mifs"
$LogString | Write-Host
Out-File -filepath $OutPath -inputobject $LogString -append
$D_T = Get-Date #get current date and time 
$LogString = "Finished processing Bad DataLdr Mifs   -  $D_T"
Out-File -filepath $OutPath -inputobject $LogString -append
$LogString | Write-Host
######################################
## Repeat_Bad_Hardware_Inventory.ps1
## by Ken LUtz (Spokane County)
## August 1, 2013
######################################
<#
.SYNOPSIS
Use this script to process the bad hardware inventory log file created via the 
ProcessSMS_InBox_HardwareInv.ps1 script
This script will:
   1) Parse out the computer name from the InventorySent_Hardware.log file
   2) List the computer name and count the number of times that it appears in 
the log file.
   3) Create a CSV file of computers with counts.
   
If a machine shows up multiple times it is a good idea to remove and reinstall 
the SCCM client.

--> Change the path used for the log file -- $InPath
--> Change the path for the output CSV file.  -- $CSVOutPath1 & $CSVOutPath2

.EXAMPLE
PS > .\Repeat_Bad_Hardware_Inventory.ps1

#>



$InPath = 
'\\<LogFilePath>\SMSSource\ConfigMgr2012\Scripts\InventorySent_Hardware.log'
$CSVOutPath1 = 
'\\<CSVPath>\SMSSource\ConfigMgr2012\Scripts\InventorySent_Hardware.csv'
$CSVOutPath2 = 
'\\<CSVPath>\SMSSource\ConfigMgr2012\Scripts\InventorySent_Hardware_1.csv'
$ValidLines = Get-Content $InPath | Select-String -Pattern "-- " -AllMatches
$AllComputers = @()
$DiffComp = @()
foreach($Line in $ValidLines)
        {
                $Line = [string]$Line
                $Idx = $Line.Indexof('-- ')
                $Idx = $IDX + 3
                $Lnth = $Line.Length
                $End = ($Lnth - $idx)
                $AllComputers += $Line.Substring($Idx,$End)
        }
        $UniqComp = $AllComputers | Select -Unique
        $Cnt_All = $AllComputers.Count
        $Cnt_Unique = $UniqComp.Count
        If($Cnt_all -eq $Cnt_Unique)
        {
                Write-Host "There are no repeat workstations in the Hardware 
Inventory log file." -ForegroundColor DarkGreen
        }
        else
        {
                Write-Host "Here is the list of repeat offenders for bad 
Hardware Inventory:" -ForegroundColor DarkBlue
                $AllComputers | Sort-Object | Group-Object |Where-Object { 
$_.Count -gt 1} | Format-Table Name, Count -AutoSize
        $AllComputers | Sort-Object | Group-Object |Where-Object { $_.Count -gt 
1} | Select-Object Name, Count | Export-csv $CSVOutPath1 -NoTypeInformation 
-append
    }
    Import-CSV $CSVOutPath1 | Sort-Object -Property Name -Unique | Export-CSV 
$CSVOutPath2 -NoTypeInformation
    
    Invoke-Item $CSVOutPath2

Reply via email to