November 2017 Archives

2017-11-29 22:41:16

SharePoint Missing Setup Files Webpages

As like from my last post covers any missing webparts, that won't actually remove any webpages the SharePoing Admins created along the way.
So here's the next solution should you need to remove those web pages, if you don't wish to re-install the third party solution.

EXample Error Message:

Category        : MissingSetupFile
Error           : True
UpgradeBlocking : False
Message         : File [Features\K2WebDesignerV2\PageTemplates\K2WebDesigner.aspx] is referenced [4] times in the database 
                  [WSS_Content_OpsCentre], but is not installed on the current farm. Please install any feature/solution which contains 
                  this file.
Remedy          : One or more setup files are referenced in the database [WSS_Content_OpsCentre], but are not installed on the current 
                  farm. Please install any feature or solution which contains these files.
Locations       : 
Here's my script, just as effective and vulgur as my last one. :D
########################################################################################################################## 
# Author: Zewwy (Aemilianus Kehler)
# Date:   Oct 28, 2017
# Script: Delete-SPWebFiles
# This script allows to remove Web Parts from the Web Parts Gallery.
# Cudos to Phil Childs from get-spscripts.com
# Required parameters: 
#   A valid  SharePoint Site Collection URL and a string (case insensitive :D) for the particular SP File.
#   Best to be run from a SharePoint Mgmt Console with an account that has collection admin on the Web URL 
##########################################################################################################################

##########################################################################################################################
#   Variables
##########################################################################################################################
#The Varible used to display wrong URL provided, or not found
$BadURL = @("Sorry, the string you entered ","is not a valid Site Collection.")
#File not found from SQL query response
$BadfileQry = "Sorry mate but it seems the dingo ate your file."
#MyLogoArray
$MylogoArray = @("#####################################","# This script is brought to you by: #","#                                   #","#             Zewwy                 #","#                                   #","#####################################"," ")
#Static Variables
$ScriptName = "Delete-SPWebFiles; cause some SharePoint files just suck ass.`n"
$SQLServer = "Server\instance"
$DB = "WSS_Content"

$pswheight = (get-host).UI.RawUI.MaxWindowSize.Height
$pswwidth = (get-host).UI.RawUI.MaxWindowSize.Width

##########################################################################################################################
#   Functions
##########################################################################################################################

#function takes in a name to alert confirmation of deletion of a web part, returns true or false
function confirm($name)
{
    #function variables, generally only the first two need changing
    $title = "Confirm SharePoint File Deletion!"
    $message = "You are about to delete SharePoint File: $name"

    $yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "This means Yes"
    $no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "This means No"

    $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)

    $result = $host.ui.PromptForChoice($title, $message, $Options, 0)
    Write-Host " "
    Switch ($result)
        {
              0 { Return $true }
              1 { Return $false }
        }
}

#Function to Centeralize Write-Host Output, Just take string variable parameter and pads it
#Nerd Level over 9000!!! Ad-hoc Polymorphic power time!!
function Centeralize()
{
  param(
  [Parameter(Position=0,Mandatory=$true)]
  [string]$S,
  [Parameter(Position=1,Mandatory=$false,ParameterSetName="color")]
  [string]$C
  )
    $sLength = $S.Length
    $padamt =  "{0:N0}" -f (($pswwidth-$sLength)/2)
    $PadNum = $padamt/1 + $sLength #the divide by one is a quick dirty trick to covert string to int
    $CS = $S.PadLeft($PadNum," ").PadRight($PadNum," ") #Pad that shit
    if ($C) #if variable for color exists run below
    {    
        Write-Host $CS -ForegroundColor $C #write that shit to host with color
    }
    else #need this to prevent output twice if color is provided
    {
        $CS #write that shit without color
    }
}

#Function provided by phil to check the content database via the sharepoint front end server
function Run-SQLQuery ($SqlServer, $SqlDatabase, $SqlQuery)
{
    $SqlConnection = New-Object System.Data.SqlClient.SqlConnection
    $SqlConnection.ConnectionString = "Server =" + $SqlServer + "; Database =" + $SqlDatabase + "; Integrated Security = True"
    $SqlCmd = New-Object System.Data.SqlClient.SqlCommand
    $SqlCmd.CommandText = $SqlQuery
    $SqlCmd.Connection = $SqlConnection
    $SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
    $SqlAdapter.SelectCommand = $SqlCmd
    $DataSet = New-Object System.Data.DataSet
    $SqlAdapter.Fill($DataSet)
    $SqlConnection.Close()
    $DataSet.Tables[0]
}

#Start actual script by posting and asking user for responses
foreach($L in $MylogoArray){Centeralize $L "green"}
Centeralize $ScriptName "White"
#Notify User to enter the Site Collection URL then check if it exits.
Centeralize "Please enter a SP Site Collection URL`n"
Write-host "SharePoint Site Collection URL: " -ForegroundColor Magenta -NoNewline
$SPSitecolstr = Read-Host
Write-Host " "
Centeralize "Verifying SharePoint Site Collection URL, Please Wait...`n" "White"
if ($SPSiteCol=Get-SPSite $SPSitecolstr -EA SilentlyContinue)
{
    $DB = $SPSiteCol.ContentDatabase.Name
    $SQLServer = $SPSiteCol.ContentDatabase.Server
    Centeralize "Phhhh, ok good guess, that is a site collection here's what the systems got:`n" "Cyan"
    Centeralize "SqlSever\Instance: $SQLServer Using Database: $DB `n" "White"
    Write-host "What file you lookin' for boy?: " -ForegroundColor Magenta -NoNewline
    $StupidFile = Read-Host
    Write-Host " "
    $Shitfile = "'%"+$StupidFile+"%'"
    try
    {
        [System.Collections.ArrayList]$ShitArray = Run-SQLQuery -SqlServer $SQLServer -SqlDatabase $DB -SqlQuery "SELECT * from AllDocs where SetupPath LIKE $Shitfile" -ErrorAction Stop
    }
    catch
    {
        $BadfileQry += " This `"$StupidFile`""
        Centeralize "$BadFileQry" "Red"
        Break
    }
    $ShitArray.RemoveAt(0) #For some reason the query's first result (or more to say the first element in the object array) was the result amount, so remove it from the array
    #$ShitArray | select Id, SiteId, DirName, LeafName, WebId, ListId | Format-List
    #$ShitArray.Count #entered for testing purposes, should be removed
    foreach($ShittyFile in $ShitArray)
    {
        $SPWeb = $SPSiteCol | Get-SPWeb -limit all | where {$_.ID -eq $ShittyFile.WebId}
        $SPWURL = $SpWeb.Url
        if(!$SPWURL.EndsWith("/")){$SPWURL+="/"}
        $file = $SPWeb.GetFile([Guid]$ShittyFile.ID)
        $fn = $file.Name
        Centeralize "File Found: $SPWURL$fn" "Yellow"
        if (confirm $SPWURL$fn)
                {
                    Centeralize "Deleting Web File: $SPWURL$fn`n" "Red"
                    $file.Delete() 
                } 
    }   
}
else
{
    $SPSitecolstr = "`""+$SPSitecolstr+"`" "
    $BadURL = $BadURL[0] + $SPSitecolstr + $BadURL[1]
    foreach($str in $BadURL){Centeralize $str "red"}
}

Posted by Aemilianus Kehler | Permanent link

2017-11-29 22:23:14

SharePoint Missing Setup Files Webparts

As like from my last post covers any missing features, that won't actually remove any webparts the third party application installed along the way.
So here;s the next solution should you need to remove those web parts, if you don't wish to re-install the third party solution.

EXample Error Message:

Category        : MissingSetupFile
Error           : True
UpgradeBlocking : False
Message         : File [Features\SourceCode.SharePoint.WebPart.Reporting14_ReportingWebparts\ActivityGraph\ActivityGraph.webpart] is 
                  referenced [1] times in the database [WSS_Content_OpsCentre], but is not installed on the current farm. Please install 
                  any feature/solution which contains this file.
Remedy          : One or more setup files are referenced in the database [WSS_Content_OpsCentre], but are not installed on the current 
                  farm. Please install any feature or solution which contains these files.
Here's my script, just as effective and vulgur as my last one. :D
Solution:
########################################################################################################################## 
# Author: Zewwy (Aemilianus Kehler)
# Date:   Oct 28, 2017
# Script: Delete-SPWebParts
# This script allows to remove Web Parts from the Web Parts Gallery.
# Cudos to Carlos from Technet Galleries  
# Required parameters: 
#   A valid root SharePoint Web URL and a case senstive string for the particular Web Part.
#   Best to be run from a SharePoint Mgmt Console with an account that has collection admin on the Web URL 
##########################################################################################################################

##########################################################################################################################
#   Variables
##########################################################################################################################

#The Variable used to display the message that no web parts were found.
$NoWPFound = "Sorry to inform you, but the system returned no results for deletion. :("

#The Varible used to display wrong URL provided, or not found
$BadURL = "Sorry doofus that is not a known SharePoint Web URL"

#MyLogoArray
$MylogoArray = @("#####################################","# This script is brought to you by: #","#                                   #","#             Zewwy                 #","#                                   #","#####################################"," ")

#Static Variables
$pswheight = (get-host).UI.RawUI.MaxWindowSize.Height
$pswwidth = (get-host).UI.RawUI.MaxWindowSize.Width

##########################################################################################################################
#   Modules
##########################################################################################################################

#Load Sharepoint Modules
If ((Get-PSSnapIn -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null )  
{ Add-PSSnapIn -Name Microsoft.SharePoint.PowerShell }


##########################################################################################################################
#   Functions
##########################################################################################################################

#function takes in a name to alert confirmation of deletion of a web part, returns true or false
function confirm($name)
{
    #function variables, generally only the first two need changing
    $title = "Confirm WebPart Deletion!"
    $message = "You are about to delete WebPart: $name"

    $yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "This means Yes"
    $no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "This means No"

    $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)

    $result = $host.ui.PromptForChoice($title, $message, $Options, 0)

    Switch ($result)
        {
              0 { Return $true }
              1 { Return $false }
        }
}

#Function provided by phil to check the content database via the sharepoint front end server
function Run-SQLQuery ($SqlServer, $SqlDatabase, $SqlQuery)
{
    $SqlConnection = New-Object System.Data.SqlClient.SqlConnection
    $SqlConnection.ConnectionString = "Server =" + $SqlServer + "; Database =" + $SqlDatabase + "; Integrated Security = True"
    $SqlCmd = New-Object System.Data.SqlClient.SqlCommand
    $SqlCmd.CommandText = $SqlQuery
    $SqlCmd.Connection = $SqlConnection
    $SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
    $SqlAdapter.SelectCommand = $SqlCmd
    $DataSet = New-Object System.Data.DataSet
    $SqlAdapter.Fill($DataSet)
    $SqlConnection.Close()
    $DataSet.Tables[0]
}

#Function that delete Web Parts from the Web Parts catalog 
function RemoveWebPartsFromCatalog ($SPWA, $TSFWP)
{    
    try 
    {    
        #Variable to hold the Web Part Catalog, I'm not sure exactly why this line is here       
        $wpCatlog = [Microsoft.SharePoint.SPListTemplateType]::WebPartCatalog
        #This on creates a variable to hold the list of all the web parts located in the catalog
        $WPList = $SPWA.GetCatalog([Microsoft.SharePoint.SPListTemplateType]::WebPartCatalog)
        #Orginally i attmpted to delete the web part directly in the inital foreach loop
        #However since the item wanting to be deleted is part of the system array variable we are iterating through
        #It would crash the script after deleting the first item asked to successfully, instead
        #theres a variable used to contain all the web part ids to run a second foreach loop
        $wpIDlist = @()      
        foreach ($spItem in $WPList.Items)  #Iterating through all web parts
        {
            $S1=$TSFWP.ToLower();$S2=$spItem.DisplayName.ToLower(); # To deal  with case sensitivity   
            if($S2.Contains("$S1")) #Check for given string (this is the case senstive bullshit part)
            {  
               # $wpName = $spItem.DisplayName
               # Centeralize "Web Part Found!: $wpName" "yellow"
               # Write-Host "Web Part ID!: " $spItem.ID
                $wpIDlist += $spItem.ID 
            }                                   
        }
        #if No Web Part Found 
        if($wpIDlist.Count -eq 0)
        {
            Centeralize $NoWPFound "yellow"
        }
        else
        {
            foreach($wp in $wpIDlist)
            {
                $wpItem = $WPList.GetItemById($wp)
                $wpName = $wpItem.DisplayName
                Centeralize "Web Part Found!: $wpName" "yellow" 
                if (confirm $wpItem.DisplayName)
                {
                    Centeralize "Deleting Web Part: $wpName`n" "Red"
                    $wpItem.Delete() 
                } 
            }
            $WPList.Update()
        }     
        $WPList.Update() 
        $SPWA.Dispose()     
    } 
    catch [System.Exception] 
    { 
        write-host -f red $_.Exception.ToString() 
    } 
}

#Function to Centeralize Write-Host Output, Just take string variable parameter and pads it
#Nerd Level over 9000!!! Ad-hoc Polymorphic power time!!
function Centeralize()
{
  param(
  [Parameter(Position=0,Mandatory=$true)]
  [string]$S,
  [Parameter(Position=1,Mandatory=$false,ParameterSetName="color")]
  [string]$C
  )
    $sLength = $S.Length
    $padamt =  "{0:N0}" -f (($pswwidth-$sLength)/2)
    $PadNum = $padamt/1 + $sLength #the divide by one is a quick dirty trick to covert string to int
    $CS = $S.PadLeft($PadNum," ").PadRight($PadNum," ") #Pad that shit
    if ($C) #if variable for color exists run below
    {    
        Write-Host $CS -ForegroundColor $C #write that shit to host with color
    }
    else #need this to prevent output twice if color is provided
    {
        $CS #write that shit without color
    }
}

#Start actual script by posting and asking user for responses
foreach($L in $MylogoArray){Centeralize $L "green"}
Centeralize "Delete-SPWebParts; cause some Web Parts just suck ass.`n" "White"
#Notify User to enter the Site Collection URL then check if it exits.
Centeralize "Please enter a SP Web URL`n"
Write-host "SharePoint Web URL: " -ForegroundColor Magenta -NoNewline
$SPWebURL = Read-Host
Write-Host " "
Centeralize "Verifying SharePoint web URL, Please Wait...`n"
if ($SPWeb=Get-SPWeb $SPWebURL -EA SilentlyContinue)
{
    Centeralize "K, The SPWeb URL you entered appears to be valid.`n" "Cyan"
    if(!$SPWeb.IsRootWeb){Centeralize "But it is not a root web, you fail!" "Red"; Exit}
    Write-Host "Sigh... This HAS to be case sensitive.`nNow what does the Web Part name you are looking for contain? " -ForegroundColor Magenta -NoNewline
    $SPWPS = Read-Host
    #Write-Host " " #Need this to make new line
    #if(Confirm "$SPWPS from: $SPWebURL")
    #{
        $Ugh = @(" ","Attempting to locate web parts with the parameters you defined.","Please Wait.","I must say you are not making this easy."," ")
        foreach($lineitem in $Ugh){Centeralize $lineitem "Cyan"}
        RemoveWebPartsFromCatalog $SPWeb $SPWPS
    #}
}
else
{
    Centeralize $BadURL "red"
}

Posted by Aemilianus Kehler | Permanent link

2017-11-10 22:47:19

SharePoint Missing Feature

This is the message you'll see about missing features:
Category        : MissingFeature
Error           : True
UpgradeBlocking : False
Message         : Database [WSS_Content_OpsCentre] has reference(s) to a missing feature: Id = [a59ff911-7eb6-4671-abea-079e58218fde],
                  Name = [K2 Site Settings], Description = [Adds the K2 Site Settings link to the Site Actions menu, allowing for
                  configuration of K2 components in the site collection.], Install Location = [K2SiteSettings].
Remedy          : The feature with Id a59ff911-7eb6-4671-abea-079e58218fde is referenced in the database [WSS_Content_OpsCentre], but is
                  not installed on the current farm. The missing feature may cause upgrade to fail. Please install any solution which
                  contains the feature and restart upgrade if necessary.
This isn't anything new, it has been discussed here and also here. While Phil and Eitenne did a good job with their scripts (Phils was a big source for my own) they didn't exactly meet my expectations.
That mostly being being able to run a script without editing it and be able to clean up my mess. Now you might think that soudns rediculous cause everyones enviroemnt is different.
While I do agree there, that doesn't mean ones scipt can't ask for these variables instead of having to edit the script to define them.
Here's my script and a picture of what I mean.



If you think this is cool and exactly what you need to fix your SharePoint. Have at my code, I offer it as is, without warranty, and use at your own risk.
This is one of 4 scripts to be released on an epic Sharepoint adventure!
########################################################################################################################## 
# Author: Zewwy (Aemilianus Kehler)
# Date:   Oct 28, 2017
# Script: Remove-SPSiteFeature
# This script allows to remove Site Collection Features.
# Cudos to Phil Childs from get-spscripts.com
# Required parameters: 
#   A valid  SharePoint Site Collection URL and a string (case insensitive :D) for the particular SP Feature.
#   Best to be run from a SharePoint Mgmt Console with an account that has collection admin on the Web URL 
##########################################################################################################################

##########################################################################################################################
#   Variables
##########################################################################################################################
#The Varible used to display wrong URL provided, or not found
$BadURL = @("Sorry, the string you entered ","is not a valid Site Collection.")
#File not found from SQL query response
$BadfileQry = "Sorry mate but it seems the dingo ate your file."
#MyLogoArray
$MylogoArray = @("#####################################","# This script is brought to you by: #","#                                   #","#             Zewwy                 #","#                                   #","#####################################"," ")
#Static Variables
$ScriptName = "Remove-SPSiteFeature; cause some SharePoint features just suck ass.`n"
$SQLServer = "Server\instance"
$DB = "WSS_Content"

$pswheight = (get-host).UI.RawUI.MaxWindowSize.Height
$pswwidth = (get-host).UI.RawUI.MaxWindowSize.Width

##########################################################################################################################
#   Functions
##########################################################################################################################

#function takes in a name to alert confirmation of deletion of a web part, returns true or false
function confirm($name)
{
    #function variables, generally only the first two need changing
    $title = "Confirm SharePoint Feature Removal!"
    $message = "You are about to remove a SharePoint Feature: $name"

    $yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "This means Yes"
    $no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "This means No"

    $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)

    $result = $host.ui.PromptForChoice($title, $message, $Options, 0)
    Write-Host " "
    Switch ($result)
        {
              0 { Return $true }
              1 { Return $false }
        }
}

#Function to Centeralize Write-Host Output, Just take string variable parameter and pads it
#Nerd Level over 9000!!! Ad-hoc Polymorphic power time!!
function Centeralize()
{
  param(
  [Parameter(Position=0,Mandatory=$true)]
  [string]$S,
  [Parameter(Position=1,Mandatory=$false,ParameterSetName="color")]
  [string]$C
  )
    $sLength = $S.Length
    $padamt =  "{0:N0}" -f (($pswwidth-$sLength)/2)
    $PadNum = $padamt/1 + $sLength #the divide by one is a quick dirty trick to covert string to int
    $CS = $S.PadLeft($PadNum," ").PadRight($PadNum," ") #Pad that shit
    if ($C) #if variable for color exists run below
    {    
        Write-Host $CS -ForegroundColor $C #write that shit to host with color
    }
    else #need this to prevent output twice if color is provided
    {
        $CS #write that shit without color
    }
}

#Found Function, to be called whenever the feature is found... Sorry guys I kinda had bad code using the break, whoopsie.
function FoundItinWeb($ss, $SPF)
{
    $FName = "Feature Found: "+$SPF.Definition.DisplayName
    Centeralize $FName "Yellow"
    
    #[System.Collections.ArrayList]$ShitArray = "Parent Site: "+$SPFeature.Parent.Url,"Feature guid: "+$SPFeature.DefinitionId.Guid #,"Feature ID: "+$SPFeature.Definition.Id,"Feature Name: "+$SPFeature.Definition.DisplayName,"Compatibility Level: "+$SPFeature.Definition.CompatibilityLevel,"Physical File: "+$SPFeature.Definition.RootDirectory,"Scope: "+$SPFeature.$SPFeature.FeatureDefinitionScop)
    [System.Collections.ArrayList]$ShitArray = @("Parent Site: "+$SPF.Parent.Url)
    $ShitArray += "Feature guid: "+$SPF.DefinitionId.Guid
    $ShitArray += "Feature ID: "+$SPF.Definition.Id
    $ShitArray += "Feature Name: "+$SPF.Definition.DisplayName
    $ShitArray += "Compatibility Level: "+$SPF.Definition.CompatibilityLevel
    $ShitArray += "Physical File: "+$SPF.Definition.RootDirectory
    $ShitArray += "Scope: "+$SPF.FeatureDefinitionScope

    foreach($line in $ShitArray){Centeralize $line "white"}
    $FName = $SPF.Definition.DisplayName
    if(confirm $FName)
    {     
        Centeralize "Deleting SharePoint Feature $FName`n" "Red"
        $ss.Features.Remove($SPF.DefinitionId, $true)
    }
}

function FoundIt()
{
    $FName = "Feature Found: "+$SPFeature.Definition.DisplayName
    Centeralize $FName "Yellow"    
    [System.Collections.ArrayList]$ShitArray = @("Parent Site: "+$SPFeature.Parent.Url)
     $ShitArray += "Feature guid: "+$SPFeature.DefinitionId.Guid
     $ShitArray += "Feature ID: "+$SPFeature.Definition.Id
     $ShitArray += "Feature Name: "+$SPFeature.Definition.DisplayName
     $ShitArray += "Compatibility Level: "+$SPFeature.Definition.CompatibilityLevel
     $ShitArray += "Physical File: "+$SPFeature.Definition.RootDirectory
     $ShitArray += "Scope: "+$SPFeature.FeatureDefinitionScope

     foreach($line in $ShitArray){Centeralize $line "white"}
     $FName = $SPFeature.Definition.DisplayName
     if(confirm $FName)
     {     
         Centeralize "Deleting SharePoint Feature $FName" "Red"
         $SPSiteCol.Features.Remove($SPFeature.DefinitionId, $true)
     }
     #Remember the site is checked first, so even if the feature is found in the main site we don't want to forget each sub site
     TryWeb
}

function TryWeb()
{
        $SSW = $SPSiteCol | Get-SPWeb
        foreach($ss in $SSW)
        {
            $SPWFeature=$ss.Features[$StupidFeatureStr]
            if($SPWFeature)
            {
                FoundItInWeb $ss $SPWFeature
            }
        }
        Write-Host "Script is done."
}

#Start actual script by posting and asking user for responses
foreach($L in $MylogoArray){Centeralize $L "green"}
Centeralize $ScriptName "White"
#Notify User to enter the Site Collection URL then check if it exits.
Centeralize "Please enter a SP Site Collection URL`n"
Write-host "SharePoint Site Collection URL: " -ForegroundColor Magenta -NoNewline
$SPSitecolstr = Read-Host
Write-Host " "
Centeralize "Verifying SharePoint Site Collection URL, Please Wait...`n" "White"
if ($SPSiteCol=Get-SPSite $SPSitecolstr -EA SilentlyContinue)
{
    $DB = $SPSiteCol.ContentDatabase.Name
    $SQLServer = $SPSiteCol.ContentDatabase.Server
    Centeralize "Phhhh, ok good guess, that is a site collection here's what the systems got:`n" "Cyan"
    Centeralize "SqlSever\Instance: $SQLServer Using Database: $DB `n" "White"
    Write-host "Please enter the feature ID string: " -ForegroundColor Magenta -NoNewline
    $StupidFeatureStr = Read-Host
    Write-Host " "
    $SPFeature = $SPSiteCol.Features[$StupidFeatureStr]
    if(!$SPFeature)
    {
        Write-Host "Not Found in main site.... Trying Web"
        TryWeb
    }
    else
    {
         #Call Found Function
         Write-Host "Found in main site running found it function."
         FoundIt
    }

}
else
{
    $SPSitecolstr = "`""+$SPSitecolstr+"`" "
    $BadURL = $BadURL[0] + $SPSitecolstr + $BadURL[1]
    foreach($str in $BadURL){Centeralize $str "red"}
}   

Posted by Aemilianus Kehler | Permanent link

2017-11-01 19:46:26

Clearing the cache

This one will be nice and short. I was working on a DNZ zone migration, from one domain to another. Since the zone wasn't the parent zone of the AD domain it was in I had two options.
One make the new domain authorative for the zone, once trust is established they would take over for the zone.
Or in this case since there were only a few records and the new AD domain was already created with the same domain anem as the zone I was attempting to migrate, I figured I'd simply recreate the records manually.
Basically setup your conditional forwarders to the new domain DC's which will be authorative for the new zone. Generally allow UDP (TCP as well if you want to be extra safe) on port 53 through the firewall, and records should resolve just fine.
In this case you'll clearly notice that resolving the record for the transferred zone from the orginal domain now replies with non-authorative answer.
This is to be expected as the domain's DC that you are associated with (and generally your DNS settings configured to via DHCP of course) are no longer controlling the zone (adding/removing/editing records).
Again as to be expecting these are now managed via the new domain which teh zone was transferred to.

So low and behold I messed u one of the records IP addresses. So sure it's super fast to adjust and force replication, however replication would be domain/forest wide. Which even though I did on both domains i found my previous DC's would update the non-authorative answer.
I tripple checked all systems in teh new domain could get the proper reply from the DC/DNS servers. So what gives why were the old DC's DNS servers replying with the old IP address, when the conditional forwarders were setup to query the proper DNS servers and they were 100% holding the correct IP address?
The answer? Cache? yup the lovely blessing and nightmare that is cache. so what does any regular workstation admin try... yeah you guessed it "ipconfig /flushdns" (cmon were talking AD here which is Microsoft specific AFAIK). Do a query from your old domain DC's and yet the record is still the old IP adress?!?!
What gives? Well... in this case ipconfig /flushdns is only used for clients. You maybe wondering isn't the old DC a client in this case? Yes/No It's still a DNS server, and it still needs to answer queries it recieves, the command provided would help if simply doing a query (yes we are doing a query but for a record it needs to hold a record for to reply with).
Just to stop beating around the bush, as a DNS server it needs to clear its own cache, the records to retains to provide to requesting clients. this is a different command. in this case it's dnscmd /clearcache.
That's it, do another lookup and find your old DC DNS servers showing a non-authorative answer of the new IP address. Of course you could have also simply waited for cache to clear and replication to occur naturally... but ain't no body got time for that!

 1) To Clear Dns from a client system (Windows): ipconfig /flushdns
 2) To clear non-authortive DNS servers cache:	 dnscmd /clearcache

Posted by Aemilianus Kehler | Permanent link