ACS Blogs

A blog site for Architecting Connected Systems staff to tell the world about their exploits in
SharePoint 2007/2010/2013, Windows Workflow Foundation (3.0/4.0) and other great technologies!
Welcome to ACS Blogs Sign in | Join | Help
in Search
MSPress

CJG

  • Latest Office 365 MVPs

    In keeping with previous posts, here is a list of all Office 365 MVPs as of 6/10/2015 (update coming July 1st)...At the bottom is a powershell script that you can run to follow all the SO365 MVPs in one go!

    Some quick stats...

    • 108 (non-anonymous) Office 365 MVPs

    Country breakdown:

    • 15 United States
    • 12 Not Shared
    • 7 Japan
    • 7 Sweden
    • 6 Australia
    • 6 Canada
    • 5 Brazil
    • 5 France
    • 4 Germany
    • 4 United Kingdom
    • 4 Netherlands
    • 3 Croatia
    • 2 China
    • 2 New Zealand
    • 2 Italy
    • 2 Switzerland
    • 2 Malaysia
    • 1 Mexico
    • 1 United Arab Emirates
    • 1 Vietnam
    • 1 Norway
    • 1 Peru
    • 1 Philippines
    • 1 Poland
    • 1 Portugal
    • 1 Russia
    • 1 Spain
    • 1 Bulgaria
    • 1 Austria
    • 1 Belgium
    • 1 Bosnia-Herzegovina
    • 1 Denmark
    • 1 Korea
    • 1 Latvia
    • 1 Hungary
    • 1 India
    • 1 Indonesia

    New MVPs (within last year):

    • Chris Goosen
    • David Petree
    • Elio Struyf
    • Erwin van Hunen
    • Haylee Fox
    • Johan Dahlbom
    • Knut Relbe-Moe
    • Matthew Green
    • Michael Blumenthal
    • Naohiko Maeda (?? ??)
    • Naomi Moneypenny
    • Nathan OBryan
    • Paolo Pialorsi (Paolo Pialorsi)
    • Ravikumar Sathyamurthy
    • Robert *** (Robert ***)
    • Samantha
    • Sébastien Levert
    • Susan Hanley
    • Tung Pham
    • Vasil Michev
    • Victor Meirans (Viktors Meirans)
    • Vitaly Vedenev
    • Wellington Agápto
    • Yoan Topenot
    • Yvette Watson

    Longest running\most awarded SharePoint MVPs:

    • Cindy Meister 19
    • Arnaud 12
    • Goran Husman 12
    • HeeJin Lee (Hee Jin Lee) 12
    • Nitin Sadashiv Paranjape 11
    • Tomislav Bronzin (Tomislav Bronzin) 11
    • Maarten van Stam 10
    • Scot Hillier 10

    The list (data comes from your MVP profile, you don't see it, go update it):

    NameBlogTwitter
    Agnes MolnarBlogmolnaragnes
    Alan RichardsBlogarichards_Saruk
    Alex PearceBlog
    Alvaro dos Santos RezendeBlog
    Amin TavakoliBlogamintvk
    Arnaud Blogalcabeza
    Ayman Mohammed El-HattabBlogaymanelhattab
    Ben CurryBlog
    Benjamin NiaulinBlogbniaulin
    Benoit HAMETBlogbenoit_hamet
    Brendon FordBlogstewartisland
    Brett HillBlogbretthill
    Brian NøhrBlogbsnohr
    Byeongguk KuBlog
    Chris GoosenBlog
    Christian BuckleyBlogbuckleyplanet
    Cindy MeisterBlog
    Dan HolmeBlogdanholme
    Danny BurlageBlogdannyburlage
    Darrell C Webster (Darrell Webster)Blog
    David PetreeBlogdmixx
    Dean HowarthBlog
    Diogo Dias HeringerBlog
    Dragan PanjkovBlogpanjkov
    Elio StruyfBlogeliostruyf
    Emre AydinBlog
    Erwin van HunenBlog
    Eunjoo Lee (Eunjoo Lee)Blog
    Fernando AndreaziBlogfandreazi
    Genki WatanabeBloggenkiw
    Geoff EvelynBlog
    Gilles PommierBlog
    Goran HusmanBlog
    Haylee FoxBlog
    HeeJin Lee (Hee Jin Lee)Blog
    Igor PavlekovicBlogigorpnet
    J. Peter BruzzeseBlog
    Jasper Oosterveld (Jasper Oosterveld)Blogjasoosterveld
    Jeremy DahlBlog
    Jesper StåhleBlogJesperStahle
    Jethro SeghersBlogjseghers
    Jian Chen (??)Blogloveunicom
    Johan DahlbomBlogdaltondhcp
    Jorge Castañeda CanoBlogxorxe
    Juan Carlos Gonzalez Martin (Juan Carlos González)Blogjcgm1978
    Kamil Baczyk (Kamil Baczyk)BlogKamilBaczyk
    Kanwal KhippleBlogkkhipple
    Kazuhiko ?? Nakamura ??Blog
    Kelsey EppsBlogkelseyepps
    Kerstin RachfahlBloghimmlischeit
    Knut Relbe-MoeBlogsharePTkarm
    Laurent Miltgen-DelinchampBlog
    Liang Tang (??)Blog
    Loryan StrantBlogthecloudmouth
    Maarten van StamBlogaafvstam
    Magnus BjorkBlog
    Malin DandenellBlog
    Mario Cortes FloresBlog
    Markus WidlBlogmarkuswidl
    Martina GromBlogmagrom
    Matthew GreenBlogmattdgreen
    Mauricio CassemiroBlog
    Michael Kirst-NeshvaBlogankbs
    Michael BlumenthalBlog
    Michael WashingtonBlogADefWebserver
    Myles JefferyBlogmjthinkscape
    Naohiko Maeda (?? ??)Blognaohikomaeda
    Naoki OsadaBlog
    Naomi MoneypennyBlognmoneypenny
    Nathan OBryanBlogMCSMLab
    Nitin Sadashiv ParanjapeBlog
    Nuno Árias Silva (Nuno Árias Silva)BlogNunoAriasSilva
    Paolo Pialorsi (Paolo Pialorsi)Blog
    Patrick LamberBlogpatricklamber
    Patrick GuimonetBlogpatricg
    Paul SchaefleinBlogpaulschaeflein
    Paul WoodsBlogpaulwoods
    Poo Ching LoongBlog
    Rahmat ZikriBlogzikr1
    Raphael KoellnerBlogra_koellner
    Ravikumar SathyamurthyBlogShakthiRavi
    Rene Dominik ModeryBlogmodery
    Rie Okuda (?? ??)Blog
    Robert *** (Robert ***)Blog
    Robert D. CraneBlog
    Samantha Blog
    Sara Barbosa (Sara Barbosa)BlogSarabarbosa
    Scot HillierBlog
    Sean McNeillBlogs_mcneill
    Sébastien LevertBlogsebastienlevert
    Seiji Noro (?? ??)Blog
    Steve NoelBlogCloudItca
    Susan HanleyBlog
    Tomislav Bronzin (Tomislav Bronzin)Blogtbronzin
    Tommy ClarkeBlogitommyclarke
    Tung PhamBlog
    Ty AndersonBlog
    Vasil MichevBlog
    Victor Meirans (Viktors Meirans)Blog
    Vincent ChoyBlog
    Vitaly VedenevBlogvedenev
    Wellington AgáptoBlog
    WenXing LiaoBlog
    Yoan TopenotBlogYoanTopenot
    Yoni KirshBlog
    Yoshihide SakamotoBlog
    Yvette WatsonBlogyfwatson
    Zeljka KnezovicBlogzeljkak
  • Latest SharePoint MVPs (Twitter Follow Script)

    In keeping with previous posts, here is a list of all SharePoint MVPs as of 6/10/2015 (update coming July 1st)...At the bottom is a powershell script that you can run to follow all the SP MVPs in one go!

    Some quick stats...

    • 219 (non-anonymous) SharePoint Server MVPs

    Country breakdown:

    • 40    United States
    • 28    Not Shared
    • 22    Canada
    • 10    France
    • 8    Australia
    • 8    United Kingdom
    • 6    Switzerland
    • 6    Belgium
    • 6    India
    • 6    Japan
    • 5    Italy
    • 5    Netherlands
    • 5    Germany
    • 5    China
    • 4    Brazil
    • 4    Korea
    • 4    Spain
    • 3    Sri Lanka
    • 3    Denmark
    • 3    New Zealand
    • 2    Norway
    • 2    Pakistan
    • 2    Finland
    • 2    Costa Rica
    • 2    Sweden
    • 2    Czech Republic
    • 2    South Africa
    • 2    Taiwan
    • 1    Tunisia
    • 1    Turkey
    • 1    United Arab Emirates
    • 1    Uruguay
    • 1    Vietnam
    • 1    Croatia
    • 1    Colombia
    • 1    Guatemala
    • 1    Hungary
    • 1    Bulgaria
    • 1    Chile
    • 1    Bosnia-Herzegovina
    • 1    Argentina
    • 1    Macedonia F.Y.R.O
    • 1    Malaysia
    • 1    Jordan
    • 1    Philippines
    • 1    Portugal
    • 1    Romania
    • 1    Russia
    • 1    Singapore
    • 1    Slovenia

    New MVPs (within last year):

    • Adnan    Amin
    • Albert-Jan    Schot (Albert-Jan Schot)
    • Amit    Vasu
    • Bijaya    Kumar Sahoo (Bijay Kumar)
    • Bin    Wang
    • David    Amenda
    • Dinusha    Kumarasiri
    • Erdem    Avni SELÇUK
    • Inderjeet    Singh Jaggi
    • Jan    Vanek
    • Jussi    Roine (Jussi Roine)
    • Lakshmanan    sethu (Lakshmanan Sethu)
    • Marco    Rizzi
    • Michael    Nokhamzon
    • Mike    Maadarani
    • Prasath    Chellappan
    • Rodrigo    Romano (Rodrigo Romano)

    Longest running\most awarded SharePoint MVPs:

    • Michael    Greth    17
    • Daniel    Wessels    12
    • Robert    L. Bogue    12
    • Spencer    J Harbar    12
    • John    Timney    12
    • Rob    Windsor    12
    • Fabrice    Romelard (Fabrice Romelard)    12
    • Fumio    Mizobata (?? ???)    12
    • Pierre    Erol GIRAUDY (Erol GIRAUDY)    12
    • Ai    Yamasaki (?? ? (?? ?))    11
    • Haarón    González (Haarón González)    11
    • Adams    Chao    11
    • Ted    Pattison    11
    • Andrew    Connell    11
    • Sahil    Malik    11
    • Eli    Z. Robillard    11
    • Ed    Musters    11
    • Shane    Young    10
    • Joris    Poelmans    10
    • Hilton    Giesenow    10

    The list (data comes from your MVP profile, you don't see it, go update it):

    NameBlogTwitter
    "Michelle" Caldwell (Michelle Caldwell)Blog
    Adams ChaoBlog
    Adis JugoBlogadisjugo
    Adnan AminBlogadnan_amin
    Adrián Diaz CerveraBlogAdrianDiaz81
    Ai Yamasaki (?? ? (?? ?))Blogai_yamasaki
    Alan MarshallBlog
    Albert-Jan Schot (Albert-Jan Schot)Blog
    Alberto Diaz MartinBlogadiazcan
    Alexey SadomovBlogsadomovalex
    Amanda PerranBlog
    Amit VasuBlog
    Anders DissingBlogandersdissing
    Andre LageBlogaaclage
    Andres Felipe Rojas ParraBlogarojaspa
    Andrew ConnellBlogandrewconnell
    Andrey MarkeevBlogamarkeev
    Antonio Maio (Antonio Maio)Blog
    Ashutosh SinghBlogashutosh80
    Asif RehmaniBlogasifrehmani
    Atsuo Yamasaki (?? ??)BlogSharePointIssue
    Becky BertramBlogbeckybertram
    Ben RobbBlogbenrobb
    Benoît JesterBlogSPAsipe
    Bijaya Kumar Sahoo (Bijay Kumar)Blogfewlines4biju
    Bin WangBlog
    Bjoern H Rapp (Bjoern H Rapp)Blogbjoern_rapp
    Brandon AtkinsonBlog
    Carlos CitranguloBlogcarlocitrangulo
    Cathy DewBlogcatpaint1
    Cheng Cheng (??)Blog
    Chris GivensBloggivenscj
    Chris O'BrienBlogChrisO_Brien
    Chris McNultyBlogcmcnulty2000
    Christian GlessnerBlog
    Christopher ClementBlogClemChristopher
    Chuantao DuanBlog
    Claudio BrottoBlog
    Colin PhillipsBlogitgroove_colin
    Corey RothBlogcoreyroth
    Dan UsherBlog
    Daniel McPherson (Daniel McPherson)Blogdanmc
    Daniel WesselsBlogmosslive
    Darko MilevskiBlog
    David MannBlog
    David Sánchez AguilarBlogdavidsancheza
    David AmendaBlog
    Debbie IrelandBlogdebbieireland
    Destin N JoyBlog
    Devendra VelegandlaBlog
    Dinusha KumarasiriBlog
    Dmitri PlotnikovBlogdmiplo
    Doug WareBlog
    Doug Hemminger (Doug Hemminger)Blog
    Dux Raymond SyBlogmeetdux
    Ed MustersBlog
    Edin KapicBlogekapic
    Elaine van BergenBloglaneyvb
    Eli Z. RobillardBlog
    Erdem Avni SELÇUKBlogeravse
    Eric Alan Shupps (Eric Shupps)Blogeshupps
    Eric RizBlogrizinsights
    Fabian ImazBlogFabianImaz
    Fabian MoritzBlogFabianMoritz
    Fabian G WilliamsBlogfabianwilliams
    Fabio FranziniBlogfranzinifabio
    Fabrice Romelard (Fabrice Romelard)Blogfromelard
    Fumio Mizobata (?? ???)Blog
    Gaetan BouveretBloggbouveret
    Gavin BarronBloggavinbarron
    Giuseppe MarchiBlogPeppeDotNet
    Gokan OzcifciBlogGokanOzcifci
    Guillaume Meyer (Guillaume Meyer)Blogguillaumemeyer
    Gustavo Adolfo Velez DuqueBlog
    Haarón González (Haarón González)Bloghaarongonzalez
    Hans Brender (Hans Brender)BlogHansBrender
    Heber LopesBlogheberolopes
    Hemendra Agrawal (Hemendra Agrawal)Blog
    Hilary StoupaBlog
    Hilton GiesenowBlogthemossshow
    Hiroaki Oikawa (?? ??)BlogHiroakiOikawa
    Hirofumi OtaBloghrfmjp
    Igor Macori (Igor Macori)Blogimacori
    Inderjeet Singh JaggiBlog
    Isha KapoorBlog
    Ivan SandersBlogiasanders
    Ivan Padabed (???? ???????)Blogsharepointby
    Jake Dan Attis (J. Dan Attis)Blogjdattis
    James MilneBlogJamesMilne
    Jamie McAllisterBlog
    Jan VanekBlog
    Jason WarrenBlogjaspnwarren
    Jason HimmelsteinBlogsharepointlhorn
    Jason Kaczor (Jason Kaczor)Blogjjkaczor
    Jean PaulBlogjeanpaulmvp
    Jennifer Ann MasonBlogjennifermason
    JeongWoo ChoiBlog
    Jianyu Yang (???)Blog
    John TimneyBlog
    John D. RossBlogjohnrossjr
    John P White (John P White)Blogdiverdown1964
    John Liu (John Liu)Blogjohnnliu
    Joris PoelmansBlog
    Joseph Tu (???)Blog
    Juan Pablo Pussacq LabordeBlogjpussacq
    Juan Manuel (Manolo) Herrera (Juan Manuel Herrera Ocheita)Blogjmhogua
    Juan Andrés Valenzuela (Juan Andrés Valenzuela)Blogjandresval
    Julien ChableBlog
    Jussi Roine (Jussi Roine)Blogjussiroine
    Jussi MoriBlogJussiMori
    Justin Liu (???)BlogFoxdaveJustin
    Kamil JurikBlogKamilJurik
    Keith TuomiBlogkeithtuomi
    Kevin Trelohan (Kevin TRELOHAN)Blogktrelohan
    Kris WagnerBlogSharePointKris
    Lakshmanan sethu (Lakshmanan Sethu)Blog
    Laura Derbes Rogers (Laura Rogers)Blogwonderlaura
    Liam ClearyBloghelloitsliam
    Lionel LimozinBloglimozinlionel
    Mahmoud CHALLOUFBlog
    Marat Bakirov (????? ???????)Blog
    Marc D AndersonBlog
    Marco RizziBlogmarcorizzi
    Margriet BruggemanBlogmargrietvuur
    Marianne van WanrooijBlogmariannerd
    Marius ConstantinescuBlogc_marius
    Mark RhodesBlog
    Mark StokesBlogMarkStokes
    Martin HarwarBlogpoint8020
    Masaki NishiokaBlog
    Matthew McDermottBlogMatthewMcD
    Matthias EinigBlogmattein
    Melick Rajee BaranasooriyaBlogMelickRajee
    Michael NokhamzonBlogmickey75019
    Michael GrethBlogmysharepoint
    Michael NoelBlogmichaeltnoel
    Michal PisarekBlog
    Miguel Tabera (Miguel Tabera)Blogmigueltabera
    Mikael Svenson (Mikael Svenson)Blog
    Mike MaadaraniBlog
    Mike SmithBlogTechTrainNotes
    Mirjam van OlstBlogmirjamvanolst
    Mohammed A. SalehBlogmohkanaan
    Muhammad Imran KhawarBlogmsdev_Pakstatus571218277298348033
    Nabil BabaciBlognabilbabaci
    Nguyen Hoang Nhut (Nguyen Hoang Nhut)Blognhutcmos
    Nick KellettBlog
    Nicki BorellBlogNickiBorell
    Nicolas GeorgeaultBlogngeorgeault
    Noorez KhamisBlognkhamis
    Patrick YongBlog
    Paul OlenickBlog
    Paul Papanek StorkBlogpstork
    Penelope CoventryBlogpjcov
    Peter HolparBlog
    Peter CarsonBlogcarsonpeter
    Pierre Vivier-MerleBlog
    Pierre Erol GIRAUDY (Erol GIRAUDY)BlogEROL_MVP
    Prasath ChellappanBlog
    Radi AtanassovBlog
    Randy DrisgillBlog
    Reza AlirezaeiBlog
    Ricardo Jose MunozBlogrmunozcr
    Riwut LibinukoBlogcakriwut
    Rob FosterBlog
    Rob WindsorBlogrobwindsor
    Robert VoncinaBlogR0b3r70SP
    Robert L. BogueBlog
    Rodrigo PintoBlogScoutmanPt
    Rodrigo Romano (Rodrigo Romano)Blog
    Roger HaueterBlogtechtask
    Romeo Donca (Romeo Donca)Blogromeodonca
    Ruven GotzBlog
    Sahil MalikBlog
    Samuel ZuercherBlogsharepointszu
    Sangha BaekBlogSanghaBaek
    Scott JamisonBlog
    Sean WallbridgeBlogitgroove
    Seokhyi HanBlog
    Serge LucaBlog
    Serge TremblayBlogSergepoint
    Seung-Jin KimBlogjincrom
    Sezai KomurBlogsezai
    Shai PetelBlogshaibs
    Shane YoungBlog
    Shuguang TuBlog
    Sohel RanaBlog
    Sonja MadsenBlog
    Spencer J HarbarBlogharbars
    Stanislav VyschepanBloggandjustas
    Stéphane EyskensBlogstephaneeyskens
    Steve SmithBlog
    Steve CurranBlogspsteve
    Susitha Prabath FonsekaBlog
    Symon GarfieldBlogsymon_garfield
    Ted PattisonBlog
    Thomas VochtenBlogThomasVochten
    Thorsten HansBlogThorstenHans
    Thuan NguyenBlognnthuan
    Tobias ZimmergrenBlogzimmergren
    Todd KlindtBlog
    Todd S BaginskiBlogtoddbaginski
    Toni FrankolaBlogtonifrankola
    Trevor SewardBlogNaupliusTrevor
    Usama Wahab Khan (Usama Wahab Khan)Blogusamawahabkhan
    Valy GreavuBlogvalygreavu
    Veronique PalmerBlogveroniquepalmer
    Vielka RojasBlogvkrojas
    Vijai Anand Ramalingam (Vijai Anand Ramalingam)Blog
    Vincent BiretBlogbaywet
    Vlad CatrinescuBlog
    Waldek MastykarzBlogwaldekm
    Wei DuBlog
    Wes PrestonBlogidubbs
    Wesley HackettBlogweshackett
    Wictor WilenBlogwictor
    Wonbae KimBlog
    Yaroslav PentsarskyyBlogspentsarsky
    Yasir AttiqBlog
    Posted Wednesday, June 10, 2015 10:55 PM by cjg | 1 Comments
    Filed under:

    Attachment(s): TwitterScripts.zip
  • Subnet masks are important...SharePoint Is Up...err Down

    We had this awesome situation the past 5 days.  Another team wanted to use ElasticSearch to index SharePoint.  They would attempt to connect to SharePoint, but were not able to.  Of course, the SharePoint Servers were in fact up as demonstrated by my ability to connect to them from my laptop and from other servers in the farm.  I therefore wrote them off as crazy and put down as a firewall/F5/Linux issue.  But they kept nagging at me and eventually escalated to the higher powers that be and I was forced to deal with it.  Here's how it played out:

    Quick Facts:

    • ElasticSearch on its own /28 subnet
    • SharePoint on its own /28 subnet (more on this later)
    • F5 VIPs for load balancing on both sides (both SP WFEs and ElasticSearch queries)
    • Both subnets part of a larger /24 subnet allocation pool

    The process (after 5 days of back and forth):

    • Can you ping our server IPs?  Yes
    • Can you hit our SP URLs?  No
    • What happens when you ping via DNS?  We see the F5 VIP IP
    • Change your hosts file to point to a WFE directly, can you hit our server?  Yes
    • Oh, we need a bounceback iRule for the SP servers to talk to each other, let's add that now
    • Maybe we need a reverse proxy on the VIP?  Let's add that?
    • Remove your hosts file, can you hit our servers?  No
    • Fire up wireshark on all the servers, do logging on the F5
    • Traffic flows from the ElasticSearch, through the F5 and does arrive at our SP WFE however the WFE kills the TCP connection and no IIS request is logged - WTF...
    • Chris - "OK guys, let's start at the bottom and work our way up the OSI layers..."
      • Ethernet adapters good? - Yup
      • Level 2 ok?  Yup
      • Level 3 - got IPs? Yup - Chris - "Hey, what is your guys subnet?".  Them - "255.255.255.240".  Chris - "Ours is "255.255.252.0"....***

    5 hours over 5 days wasted, frustrated, starting to think they were crazy F5 guys...all because the network guys didn't setup our subnet properly.  What was happening is the SharePoint servers had a huge subnet configured.  This caused the SP servers to think that the ElasticSearch servers were on the same subnet but weren't.  Therefore when it couldn't connect to them using layer 2, it would kill the TCP layer.  Awesome.

    Enjoy!
    Chris

  • Stop Killing Yourself Drop Kerberos - Go Claims!

    Why...why put yourself through the agony?  To be fair and relatively speaking, kerberos is easy to setup and manage, but its old and stupid.  The whole design is to keep you from tagging the auth controllers each time you login and be able to "delegate" your credentials to some other system so it can do something "on your behalf". 

    Hmm...that sounds familiar....claims based auth with auth tokens anyone?  Not a single Saas App uses kerberos...so why are you still using it?  Its just stupid.  If you have a product that relies on Kerberos, then you are living in 1999.  Fast forward 16 years later....

    YOU SHOULD DROP ALL THINGS KERBEROS.

    Drop those old apps that you don't need anymore for ones that support claims auth and have so much more functionality than the old ones you have.  It's time.  Really.  You can let go now.

    BUT CHRIS I CAN'T CUZ...THE VENDOR HASN'T UPDATED THEIR SOFTWARE....

    Well...time to drop that vendor's software.  Yeah...tell the Microsoft SQL Server team (isn't that the only reason you still use Kerberos?) to get with the times.  Its ridiculous that they don't support claims based auth and delegated auth based on Claims based tokens. 

    Time for software vendors and engineering teams to step up.  It's freakin 2015...I want my sharks with lasers damn it.

     

    Chris

     

  • Workflow Associations lost in migration

    Ran into this interesting problem today.  It is related to this long running workflow bug from this post.  As part of the eBay/PayPal split, we are creating a new domain and moving the users.  Of course, some users still exist, some do not.  No matter what, the workflow user will not exist in the target domain.  So the previous bug occurs.

    But we ran into another issue.  All the list\site workflow associations disappeared for those "User not found" workflows. Took a couple of hours, but finally figured it out.

    If you run the SPFarm.MigrateUserAccount method before updating the non-existing workflow owner to an existing person...you will LOSE ALL ASSOCIATIONS for all the workflows across the farm that the previously migrated user owned!  Ouch...

    Lesson learned...be sure to update the workflow modifiedby first, then migrate your users!

    Chris

  • Delve vs Box : What the heck is Delve? Don't baby me...don't tech me...give it to me straight! -

    At @MS_Ignite I had a very fun, cool, awesome session that we affectionately called "Battle of the Office Graph".  Can you tell from the pic?

    Huh, you said Delve in the blog title, why now are you saying "Office Graph"?  Well, that's what this blog post is here to enlighten you about!  So let me explain...the "Office Graph" is the basis for a series of "signals" or "events" that occur in the O365 eco-system that are fed into the SharePoint Search index.  These signals can be a myriad of different things such as "Create", "Update", "Email", blah blah (you can learn all about it here).  These events also have properties that are indexed such that you can "query" them via the SharePoint Search APIs.  So...back to the question that was asked over and over again at the Delve booth at @MS_Ignite...

    What is Delve? 

    This O365 page tries to tell you, but kinda fails miserably.  Delve, my friends, is simply a UI on top of the SharePoint Search index (yeah...that awesome Ceres code built by the amazingly cool and crazy smart Norwegians that I love to hang out with!) that shows you these various events that you or other people have generated in a "meaningful" way.  At least...that's how it started out anyway.  as some other people have started to notice, the page is taking on the new persona of the "My Profile" page, only rebranded as "Delve". The "meaningful" way is simply a basic set of queries that the Search team put together that they think makes the most sense for a majority of people and organizations on the planet.  Will it work for you?...probably...is it optimal for you?  Maybe not. If you check out Wikipedia...it has a horrible definition that is not even close!  Does it use machine learning and artificial intelligence...ummm no.  As a computer scientist, I can safely say that simple algorithms and data queries don't qualify for machine learning or even come close to AI.  The marketing guys did a really good job and they let the media spin this out of control! It also does not let you manage your emails or pretty much anything else that the page says (as of 5/20/2015)!

    Since it is just a simple one page app that makes Ajax calls to the Search API...this is where the ability to make your own "Delve" page (or App) comes into play.  You can create your own pages in O365 that makes calls to the Search API and build your own Delve interface(s).  Currently the default Delve UI page is not extensible unless you highjack the CDN, which you can do inside your network, but not outside it (which of course would make for a terrible user experience). Wait a few more months and you should get the ability to do some customization (although we are not sure exactly what they will entail just yet)!

    In addition, the widely awaited and anticipated "Push API" is coming very soon (likely end of 2015).  This will allow you to pump your own "signals" into the SharePoint Search index aka Office Graph aka Delve.  This will kick the crap out of Box and all the other online storage companies and anyone else that is even thinking about entering the online storage market!

    So....it's this future ability to create your own UI based off the internal and external indexed signals that makes the future of the O365 platform so exciting!  Which brings me to the second part of this blog post...comparing Delve and O365 (OneDrive) to something like Box.  Ok so yeah, they had an IPO recently.  The stock has tanked horribly...why?  Cuz Microsoft is about to destroy them.  If you are stockholder...well...I'm sorry for you.  Get out now!  I'll give them the benefit of the doubt and say its possible that they may use some of that cash to catchup, however, if they simply use it to do Merger and Acquisitions of simple disk drives...well...your screwed.

    Real life example: 

    eBay has a fairly huge presence on Box but does not use their internal OneDrive (My Site) or their O365 tenant.  Box currently provides a seamless single sign on experience that gains eBay access to cloud hosted corporate data (can you say "I don't trust internal IT"?).  However, it is missing some key features that exist in Office 365 that should make you pause and reconsider your usage of Box.  This is the current experience with eBay Box:

    eBay Box: 

    Open the Box url, type your ebay email (do NOT type your password)...

     

    Home Realm Discovery takes you to the eBay SSO (this is similar with Yammer and O365 solutions)

     

    You are presented with your eBay Box application:

     

    As you can see, not much going on.  Its just a web UI on top of some storage.  Very lame, very boring.  You don't get anything close to what Office 365 gives you!  But Box does have a couple of nice simple features that O365 does not have, keep reading...

    O365 OneDrive:

    Open the O365 login page (https://login.microsoftonline.com/) - maybe one day they will change this pic of Santa Monica to something else, been this same image for like 4 years now!


    Enter your email and again, Home Realm Discovery takes you to the eBay SSO (this is similar with Yammer and O365 solutions)

     

    Once logged in (and if you have a license assigned), you are presented with your O365 tenant.  


    At this point, without saying anything...its pretty obvious who the winner is between O365 and Box. But let's do the apples to apples thing shall we?  Clicking on OneDrive, we get the following:

     

    Both (OneDrive and Box) are similar when compared to each other directly.  But its the indirect comparisons (pick your poison, apple vs orange, which ever is better is O365) where O365 starts to kick the **** out of Box.  However, Box does have some things that OneDrive does not have...

    Box is good at:

    • Notifications (although O365 "My Site" aka OneDrive has it, it is buried and not as friendly as Box):


    • Logging - I know where I logged in from and when.  Try to find that in your O365 UI!:


    O365 is good at...everything else!

    Look at all the stuff you get with O365...seriously?!?  Box thinks they can compete?  Not even close.  Narrow-minded silicon valley hippies that just managed to pull off getting an IPO for a set of managed disks (aka hard drives).

    O365 is bad at...everything Box is good at.

    Just look at the simple design of the administration pages above.  OneDrive is a My Site hence, you go to the Settings cog->Site Settings...umm...no.  This equates to you need special training to learn to manage your "My Site" aka OneDrive.  People don't give a flying flip about a "My Site" or "Site Settings".  They want the simplicity of Box in terms of the admin.  The day the O365 team makes OneDrive simple to use with these types of admin UIs is the day the damn thing will rule the world.  Until then...its not even close.  The tech is there, but the UI is not. 

    Summary:

    That all being said.  It is the ability for your OneDrive to be fed into the Office Graph and the Delve UI that makes it so exciting.  In the "OneDrive" image above, you will notice the "Delve Test" word document in my OneDrive.  In the image below (along with injected Twitter data), you will see the document has in fact been inserted into my Office Graph! 

     

    Box doesn't have this, it's a simple web UI on top of some disk drives with Federated Auth ability...LAME!  Get off Box and go O365!

    Chris 

  • The eBay and PayPal Split

    *Posting this now, as our part of the split is pretty much done even though we still have a few more weeks before the final split of the two companies*

    As many of you know, I was asked to return as the architect to help split eBay and PayPal into two separate companies.  It was the first time I had ever been involved in "splitting" a public company into two parts.  I have been involved in merging companies, but splitting was a whole new ball game.  eBay had acquired Deloitte to advise on the regulatory rules around the split and thus-ly, they naturally would oversee all of our data split activities and approve my split plans.  Before the serious stuff...how bout some pictures of the team?

    Pictures:

    eBay Team (Vijiya, Surjan, Venu, Sukanya, Lavanya, Harika, Shanti, Asijit and some hidden faces) - I did not take this pic btw!

     

    SPS Sillion Valley and Meeting the "Gordon" himself of "Gordon Biersh" (happened whilst at eBay):

     

    Teaching the team how to play flip cup!

     

    Of course I owned pretty much everything, so "Tell Chris Everything" was burned into everyone's psych...

     

    And now the good stuff that will help the tech world....

    Active Directory
    • Users, DLs - Another team built this strategy out.  A very talented team from COO (aka Michael Noel's company).  They used custom built scripts and the expensive yet super shitty Quest Tool (now Dell) to migrate users and then keep the password in Sync.
    • Names that change and those that don't  - DL names did not get updated from "ebay" to "paypal".  As you can imagine, that would have caused a massive workload on all Applications involved.  There was however a filtering process for accounts and DLs that did not need to come over.
    • Email addresses - PayPal went to Office 365/Exchange online.  Until the very last second, eBay maintained the MX records for the "Paypal" domain.  Once the user migration started to occur (laptops to the new paypal domain), the user's email address in the ebay system would be removed.  Of course you just can't flip a switch and automatically everyone is migrated and moved.  It took about a week for single users to really start seeing the migration of the MX and Mail box to occur.
      • Tackling migrated user emails - As you can imagine, workflows and other things that relied on the User Info table for email would show the old "ebay.com" alias, but of course, many users moved to "PayPal".  I decided that rather than leak any future data between the companies via workflows or alerts (and keep with SEC and other rules), I updated all users to "paypal.com".  So users that stay at ebay will not receive an email from the PayPal system.
    • The infamous lost of certain attributes - at some point, someone did something not so bright and annihilated two of the most important AD attributes for roughly half the migrated users.  This of course caused havoc throughout the system once the changes were replicated (SharePoint solutions and 3rd party apps use these properties once replicated via FIM to the user profile).  I was on top of it and made sure the AD guys heard from the SP team before anyone else.  It took 2 days to re-replicate all the properties for 25K users, ouch.

    Permissions:

    Permissions were a pain in the ass.  The AD guys setup a trust so anyone could login from either domain.  Obviously this is a bad thing cuz then you start seeing the UserInfo table fill up with odd ball stuff.  We had some test trust splits, but I made it a point to cut the ties completely after iteration #3.  I did this by doing the following:

    • Deny the old domain - Add the web app policy that denies any old domain users from logging into the new domain and then update the access denied page to remind them to use their new domain credentials
    • Set the People Picker OU - People would see two of each other when assigned permissions or testing things, of course I would get a defect assigned from every person that thought the migration didn't happen until I got fed up and locked it down to only pull from the local site collection user info list and the new domain.

    3rd party apps

    • Vast amount of apps that must split like a cell.  Just to give you an idea:
      • Workday
      • SAP
      • SharePoint
      • Active Directory
      • Exchange
      • Human Resource systems
      • IT Ticketing (Remedy, home built)
      • Video solutions
      • File shares
      • SSO (Ping Identity)
    • Every one of these had to have a project team with PMO, architects, developers and business resources to split them off.  Super expensive and a massive undertaking!

    Content - What goes, what stays?
    The SEC and other regulatory bodies has some pretty strict rules around what could go and stay with each company.  There were several options one could have used to decide what content stayed and went:

    • Let the users tell us #1 (no guidance) - This requires user's to know what sites they use and what content is important.  Ha...I laughed my ass off at this option.  User's can never find or remember where and what they use everyday.  This would be a failure rigth off the bat
    • Let the users tell us #2 (with guidance) - build a tool that shows user's the sites they have viewed, edited whatever in the last 6 months/year. I built it, but they did not come (or rather, we didn't promote it).  User's never would have taken the time, and the business killed it as we didn't want liability for some reason.
    • Tell them what is going - We chose this option.  We did the migration about four times.  Each time we added more sites to the list of "should go".  At some point, no one complained about data missing.  See the next set of data points...

     What we used...

    • My algo ruled - We ended up using an Algorithm I built to decide what should go and what should stay.  It went something like this:  If the site used the "PayPal" master page, its good.  If the site had an owner\creater with a "Paypal.com" email address, its good.  If the site title had the name "PayPal", its good.  If the site didn't meet the first set of criteria, but had a document with the doc name having "PayPal", is was called "Mixed", it also got to go.  Legal loved the algo, signed off, and away we went.
    • Have a process - As much as the algo proved its value, there were still a set of sites that had to go no matter what.  The main intranet site was not tagged as "PayPal", but still had to go.  Shared resource sites managed by "eBay", had to go.  We put these in a special category and user's had to tell us they wanted them or they would get deleted.

    IRM - Information Rights Management

    • IRM Enabled Docs - Turns out when you migrate from one domain to another, you lose access to all IRM enabled documents.  Huh...who would have thunk it?

    Branding and MasterPages

    • 2007 strikes back! - 2007 had some weird crap in it.  My domain knowledge from the last upgrade helped me to "fix" some SP Hive files to support weird things like missing web part zones and other oddities
    • Lucky lucky - Our site creation process from 3 years ago helped us so much.  All the sites would get tagged based on the user and the templates they selected.  It made it super easy to find the PayPal sites (based on the algo above).
    • PayPal Branding - All migrated sites got PayPal branding, period.  No other companies, no eBay, therefore all master pages and other images were moved to PayPal.  It caused a bit of grief for some sites, but minor.

    Single Sign On

    • SSO to SSO - all those apps above...yep...SSO\claims enabled.  eBay has a mandate that *all* new applications much support claims based Auth.  If not, you won't sell it or install it!  This meant migrating every new PayPal instance to the new PayPal SSO.  Not an easy or quick process of course.  I have another post about using the old Kerberos shite coming soon.

    URL Migration

    • SystemUpdate - when updating listitems and files, make sure you use SystemUpdate.  It just looks tacky having a bunch of updates for URLs as people find others that have to be updated.
    • Keywords  and Best Bets - ensure that you remove old best bets (ones that point to sites that were deleted) and also make sure that you update the best bet urls so that they point to the new urls
    • InfoPath forms - forms that submit data to lists or other libraries must be updated.  I have a post from the last migration that details the hidden awesome code for in-memory InfoPath updating here
    • Title column and 255 chars - some URLs will get bigger when you replace them. Which means if the users decided to use the damn "Title" column, you will know that you can't change its type from Single Line of Text to Multi-line.  Those items are a lost cause and must be written off as much.  For the other columns, I could easily change the type to multiple lines of text and then update the URL.
    • Crawl Rules  - be sure you update your crawl rules to exclude those really dumb emails from customers that have weird stuff in them that should not show up in search results.  And all the unaccetable keywords that are not allowed in ebay and paypal systems.
    • Profile Properties - make sure you update User Profile properties (such as PictureUrl) that point to the old system to point to the new system
    • Code and Layouts files - Yeah, if you code has static AD domain references, you will have to update that.  And make sure that weird statically coded URLs in layout files are also updated.  This is super bad practice to statically code your absolute urls in your freakin layouts file.

    List template and User Solutions

    • List Templates - Just blow that shite away...its ridiculous to try to create something and see 100s of weird list templates showing up
    • User Solutions - I blew all these away, totally worthless

    Code, maintaining two code bases

    • TFS - yeah, you have to create new branches to support the changes in each company.  And at some point, they must break the link completely.  It required some serious refactoring in some cases to support both companies with one codebase.  I learned a ton of lessons around when you should put a company name in and when you should not.  In a majority of cases, NEVER put the name of the company somewhere in code.  Horrible, just horrible.
    • Company Names - and speaking about company names.  Never create columns on your lists that have the company name, especially if they will be used as refiners in your search center!  PayPal will forever more have the name "eBay" in the search results.  Bummer...

    Testing, testing, testing

    • Have a tool that doesn't suck - When browsing, editing and doing reporting, don't use HP ALM.  It is a horrible piece of junk.  That being said, find one that at least:
      • Allows users\departments to enter defects
      • Allows you to easily find defects (assigned to you or the project)
      • Ensure user's don't add to a defect rather than creating new defects (this drove me crazy and I went off on a couple of people).
      • Set priorities for resolution
      • Set Severity and resolution times
      • Make sure people know that a defect will roll to the next migration attempt (deferrable)
    • Have a killer defect manager - we had an awesome lady running our defect management, Sukanya Samal.  Very knowledgeable and very to task, just amazing.  You never know when you might have some jokers like these fellows...
    • Have some great tools - I created several tools three years ago that help with checking the health of the migrated farm.  You should too:
      • Link Checker - checks all the links across the farm recording what pages have what links.  This allows you to go back in and query the pages that didn't get all the links updated.  You can then dynamically run your Url Updater to target just these pages after you have made modifications for the outlier cases
      • Error Check - a tool I have had for a while that checks all SharePoint pages for error conditions (correlation errors, web part error, asp.net error).  Every time this would tell me if someone forgot to install a 3rd party product or some other dependent assembly somewhere.  I would then be able to fix all the pages.  It was also useful for determining pages that were also broken in production that we didn't need to fix in the migration (don't get blamed for someone elses problem!)


    Scripts, scripts and more scripts

    • Script everything! - I had over 85+ scripts for migrating the environment.  We could do a full rebuild in about 3 days.  Examples:
      • Install Farm\Add servers to farm
      • Install solutions
      • Create app pools, web apps and service apps
      • Start WFE and App services
      • Add web config entries
      • Attach CDBs
      • Create your web app policies - to add all your testers and admins
      • Create AD and BDC connections, map UPS properties
      • Deploy solutions
      • Update workflows
      • Migrate Users and Groups
      • Create Content Sources
      • Setup Best Bets (Fast and SP)
      • Delete Sites
      • Find and Replace URLs
      • Enable Full Auditing across sites
      • Setup Trusts with certs
      • Set and unghost master pages
      • etc, etc....
    • Utilize script references - I had several scripts that held our common functions and variables This allowed us to modify one file and have all the other scripts target our environments (Staging, QA, dev, production) with no changes.
    • Order Matters - don't just fire off scripts at random.  They must follow a logical order.  Take for instance...update the workflows to an existing user, then fire the MigrateUsers command.
    • Table locks matter - Same reason your OneDrive doesn't sync more than 5000 items, watch for when your scripts query over 5000 items in the DB, this causes a table lock and will stop all other scripts.

    Of course, my scripts became famous:


     Migrating Users and Groups

    • Migrate cmds -  If you have ever done a domain to domain migration, you will know the pain involved.  How do you find all the users to call the migration user\group command on?  How long does it take, and how should I execute it?  Well, turns out that you have to query *every* content database and the UserInfo table to get *every* user and group out.  You could then feed that to a PowerShell script that would update them.  But running that script as a single thread will take DAYS!  Especially with 60K+ users.  You need to create a dynamic script that queries the UserInfo table and then takes an input *char* such as "a".  You can then fire off 26 individual PowerShell scripts that cut the time rough by 26.  This runs so much faster.  Oh, and that same pattern, you do for EVERYTHING involving users.  Make a script that takes a "char" parameter and get it done oh so much faster!

    Firewalls and proxy filters 
    PayPal went security crazy.  They locked down everything.  Waaayyyy more than eBay.  You couldn't do anything without getting flagged for it in some way or another.  And just about every subnet was isolated from every other subnet.  Ouch.  Some tips...

    • F5 VIPs - ensure that your servers can use the same VIP for load balancing from inside the subnet!  This drove me crazy until I figured out what was going on.  Ensure the F5 guys add the right iRules to the VIP!
    • Outbound proxy filter - damn, when you block your own web properties and wonder why things don't work?  I find it funny that a company will lock down the outbound internet traffic to their own sites, didn't make for a very workable "crawl" system for those sites! 
    • Teams that just can't do it by themselves - eBay is going to Node.JS and Druple with ElasticSearch.  PayPal is going *ALL* Microsoft.  The new intranet team that run the eBay side were not network guys.  And they kept driving me crazy because they couldn't connect to SharePoint and saying it was my responsibility to fix it.  Bullshit.  They just needed to quit being lazy and go talk to the network guys.  Just stupid that "architects" don't know how to diagnose and resolve network issues.
    • FIPS policy - they tried to apply it, but I caught them when they tried it.  SharePoint don't work with FIPS.  It's not that SharePoint isn't secure, its just that it used some non-FIPS algos for hashing some things for speed.  Of course, enabling FIBS causes .NET to exception out anytime a piece of code uses it.  They dropped that pretty fast when I told them how bad it would be for SharePoint and all the other .NET apps on the network.  Reference this

    Networks:

    • IPs, subnets and VIPs - oh my!  Make sure your subnets are setup property...reference this

    Workflows:

    • The infamous workflow error I surfaced years ago (on top of many others) - This kept bitting me in the ass.  Every migration, every time, without fail.  Some workflows would update fine, some, not at all.  Some would update, but one file would remain.  Retarded.  I eventually had to manually fix association and workflow instances.  Not for the faint of heart.  Reference this post.
    • MigrateUsers and workflow associations - And just if injury and insult wasn't enough...death ensued.  If you run the MigrateUser command and the workflow has an invalid user on and file.Properties["vti_modified" property, you will lose those associations.  Reference ths post.

    Audiences:

    • We created the UPS from scratch.  Which means all things related to it were re-created, including audiences.  This meant that all audiences got new IDs.  These new IDs did not map to the audience settings across the list items and pages of the farm.  Ouch.  We had to update all those (but with a script of course).

    Notable Twitter Handles:

    Summary:

    Splitting a company cost a lot of money, time and resources.  I feel sorry for all the people that will have to find something to do (if their sales team doesn't close some deals and find them work) after we are completely done. We are talking 1000s of people to split eBay and PayPal.  They gotta go somewhere, the world keeps spinning and other companies have cash to burn so I guess they'll take some of this knowledge and find another project.  I know that I increased my intrinsic value from this project.  If anything, I now have a new monkier..."Chris Baba".  And some followers:

    It seems to be incredibly rare that you get asked to come back and do a project at a company almost fours years later.  Especially of the size and important of this.  Just as it was 4 years ago, this has been an incredibly exciting and amazing experience that I'll cherish as a major accomplishment to add to the many I have worked so hard for.

    Hope you learned something to support the migrations you are doing or are thinking about doing, especially those that are about splitting a company off from another!

    CJG aka "Chris Baba"
    @givenscj

  • Build, MSIgnite and Bill Baer - All recent Office Announcements

    The last Microsoft Ignite post was all fun. This one is all tech!  Here's a list of all the announcements that I could find from the last few weeks (focused on Office product group), I could care less about Windows 10 (I prefer real OSes like System/390):

    SharePoint 2016 (many of these came from Bill Baer's tweet storm Surprise):

    • SharePoint Foundation will not exist in SharePoint 2016.  I have known about this for a while...you might even go as far enough to say you can blame it on me and a couple of other people.  But this just makes sense in so many ways.  It would have been nice if they took it one more step to remove the ISO/EXE process, but too much change freaks everyone out!
    • Delve integration is coming to on-premises SharePoint 2013 - There will be a CU released later this year that will allow you to integrate your O365 Delve instance with your on-premises environment.  Think "Yammer" integration style, most likely just a nice little ole link sitting at the top somewhere.  Be sure to get your 3rd party IdP setup so the click bait is seamless!
    • Information security features - SSN regex checker for documents is coming to on-premises (already in O365)
    • Crawl 500 million items - this is necessary for the future of the Push API aka "Cloud Service Application" coming to the general public in Nov timeframe.  once you gain the ability to read/write the index, you will want to put all kinds of things in it!
    • Sign is as different user is back!  - Everyone learned a good lesson from having multiple O365 tenants...
    • Encryption in motion - more to come on this later
    • Responsive master pages - yes, they are coming; it was a painful 3+ years watching all the other tech easily adapt and evolve, but 2016 will get us there.
    • List View Thresholds - As you can imagine, the move to responsive and JS framework with REST APIs removes the older limitations, therefore, no more 5000 item list view threshold (which was more of a database issue [table lock promotion] than SharePoint)
    • Granular server roles - DistCache, Workflow, etc
    • Upgrade Path - You must upgrade from 2013.  You cannot jump from anything before 2013
    • Forefront UPS Sync - FIM is out (which is sad because it was an amazing tool)
    • New Update Model - Patch system based on O365 update methodology (always on, no downtime)
    • 10GB uploads - Why you would ever need this is beyond me.  Totally un-necessary.
    • Durable links - I gave them this idea and showed them how to do it based on Oracle Portal and a tool I built a couple years ago.  http://www.sharepointdurablelinks.com

    Office 365:

    • OWA with real time authoring details - we finally get real google doc functionality.  Took about as long as I told them it would take to build it (and yeah, you know what email I'm talking about)
    • Office integration with Skype for business - I'm hoping Skype for business brings back the fun and interaction that Hotmail messager had back in the day. 
    • Delve page updates\branding - Add your own actions to the delve page
    • Employee productivity BI Reporting - track employee's time on email, hours worked, time in meetings, etc. I will be doing another post on this later.
    • O365 Admin Workload specific Roles - aka granular permission assignment - hard to believe they called the platform secure before this announcement!
    • Login telemetry - Similiar login telemetry to Box and Yammer (when, where, how you logged in) - again hard to believe that we could call O365 secure before this.
    • Mobile Apps - More mobile apps for new features (O365 Video)

    NextGen Portals:
    First off, "NextGen Portals" is a marketing term wrapping a set of pages and apis that you "may" already know about.  It was "invented" by the one and only Mark Kashman.  It wraps the concept of several things included but certainly not limited too:

    • O365 Video - Azure media services, video stored in Azure, SP stores pointer and manages data in Azure back end
    • Infopedia - Advanced next generation of the Delve "page" - surface data and info via more search querys
    • Responsive design and inclusion of HTML5 based technology that works across mobile devices

    Delve and OfficeGraph:
    Just to be clear, Office Graph is a set of search queries that mimic "Supervised" machine learning algorithms.  In my world, I only consider "Unsupervised" machine learning to be true machine learning.  Therefore, machine learning comes later when you can inject and digest the information in much more advanced tools such as IBM Watson.  If you want to learn more about Delve and OfficeGraph, check out my post where I rip anyone who wastes money on Box.

    • Injection of developer "signals" later this year (Nov)

    Azure:

    • AzureStack - on-premises Azure instances (cloud in a box).  This is mainly designed to be implemented by hosting providers, but very large customers can also play here.
    • Dedicated O365 - Similar O365 instances are also available to be hosted on-premises

    Certainly some cool stuff...just wait until November 2015 when the really crazy amazing stuff comes out.  It will be a great ending to the year for Microsoft.
    Chris

  • Microsoft Ignite 2015 Recap

    Chicago...its my kind of town!

    I'm sure you heard that phrase more than once last week if you were actually there.  5 days of core sessions with pre-conference workshops for those that paid some extra cash.  For me...the week went something like this:

    Sat Evening - Virgin Hotels with the gang

    Lidiya and I got in on Saturday afternoon, checked into the speaker hotel (which Microsoft was nice enough to pick up this time around so thanks Microsoft)!  We checked in, headed over to the Virgin Hotel to meet the crew! 

    Of course, the crew are some of the coolest people on the planet!  Just check out some of these awesome photos!

    Once we have a couple of drinks, said hi and chatted a bit...we headed on over to the next event!

    Sat Night #1 - Chicago Next Hackathon by @bitterac aka Andrew Clark

    Mikael Svenson invited myself and Marc Anderson over to Norway earlier in the year to judge the Arctic SharePoint Challenge (@SPChallenge).  It was an amazing event that I will blog about in another post (link to follow). Here's a sneak peak at the "Council":

    Mikael had a heck of a time finding people to compete.  He ended up asking me and I said "Hell Yeah!".  And of course I then asked my good friend Shannon Bray and he totally went for it! 

    ChicagoNext is all about having local high schoolers compete with industry professionals on technology problems facing non-profits in the Chicago area.  I had no idea what to expect from this event, venue or anything else!  We ended up in a very random part of Chicago's suburbs.  At least a mile away from the bustling of downtown Chicago. They gave us five problems to solve...everyone took the "Access Services" solution...we choose something just a bit more difficult...lol.

    You can view some pics from the event here (yeah...I know about the t-shirt):

    https://www.flickr.com/photos/131420056%40N08/sets/72157650264255274?rb=1

    Of course we watched the "cat fight" that night too:

    Sat Night #2 - Back at the Virgin Hotels

    Once Mikael, Shannon and I formulated our plan, we headed back to the Virgin to check on the "crew".  It was not pretty...we left all the girls will Bill and he did his best to manage, but alias...the girls got the best of him (don't ask me what ole boy is doing in the background (I cut him out)...lol):

    Sunday - Chicago Next Hackathon

    Back to the grind!  We got back to the venue at 9am and started coding!  Our solution ended up being a solution to problem #4. Shannon was our DBA and Azure Specialist...I guess.  He helped build the sql tables to support our solution.  Mikael built out our Web API layer to support the API calls from my Windows Phone Mobile App.  Our solution would set up GeoFences around "event" locations to keep track if volunteers would enter or exit the geo fence.  If you were inside, we counted your time towards helping with the event, if not, well...you didn't get any credits.  We tested this by going around the corner to the local bar and amazingly...finding some Arrogant *** beer to drink.  Even @JThake joined in the fun with a hot babe...later I realized, as we got closer to the corner...it was my lovely wifey!  The goal was to provide a seamless solution to track volunteers so non-profits could tag tangible stats to grants and grant applications.  We had the best technical solution by far...unfortunately...we bombed our presentation (we blame Shannon's demo god karma)...we did get off to a great start with my "Lettttsssss get ready to rummmbbbbleee" opening in Round 6....

    Monday - Ignite Day #1

    Can you say "long corridor"?  I knew you could.  That was crazy.  It definitely showed in the attendance of sessions on one side versus the other.   A lot of people stayed on one side or the other.  I didn't quite make the keynote, I did watch it from Channel 9 and I have to say...it was oh so much better from the comfort of my room!

    Monday night

    #SharePint at the Virgin Hotel.  Holy cow...what a crazy party!  Sooo many people showed up for the drinks and of course...the DJ! 

    The party would have kept going...but unfortunately someone tried to jack some bottles of vodka and they cut us off (single double fisted would have been fine)...guess that qualifies for EPIC party right?!?  The evening continued on the Virgin's 2nd floor bar and well into the night!  Good times, definitely something I won't forget!

    Tuesday - Ignite Day #2

    Can you say..."hangover"?...yeah...I knew you could. This is when it kicked in that the bus schedule was pretty much...let's say in the words of Mikael..."that's stupid".  Buses didn't run all day?  Yup...cutoff at 10:30ish everyday.  That was just absurd.  Next year they better run all day long.  Olaf, et all, you really screwed the pooch on this one.  The food is forgivable (if even that words needs mentioned)...those of you that complained about it...just try making food for 22K people.  Yeah...that's what I thought.  It wasn't the best...but it wasn't the worst either.  Since we are on the topic...let's just bring up a couple of other things:

    • Vendors (who spent several more thousands of dollars than attendees), didn't get food.  Yeah, they would have loved to have that sub-standard food, but they didn't get any. 
    • Speakers didn't get any distributed materials.  This is fair (being our flight and hotel was taken care of), but it was a surprise. I know I wasn't the only one to be surprised about this!

    Vegas didn't play ball.  Vegas has so many conferences...they just demand what they want.  Microsoft was getting screwed over so bad having the conference in Vegas it just wasn't even funny.  Chicago (which is on the verge of insolvency) was so accommodating to the conference.  So much so...they won next year during the week.  That being said, it makes sense that we can only hope that the entertainment will be better next year (this was the second year that I didn't attend the attendee party...wonder why).

    Tuesday Night Parties!

    There was only one for us. The AvePoint party setup by the amazing Julie (@JulieLiu). The rest, I heard, were good, but nothing ever compares to the AvePoint party.  It was hosted at the lovely Chicago Station.  This was the view from my seat:

    And of course, a shout out to the awesome, amazing CEO of AvePoint...TJ...yes...I wore an @AvePoint_Inc shirt and red "hot chilli" pants:

    Wednesday - Ignite Day #3

    The big day!  Battle of the Graph was at 5pm.  I spent most of the day prepping in the speaker room where I met one of my security and identity idols...the one and only...@vibronet:

    If you didn't see the pre-session promos...well...you totally missed out...check out this photo from one of Mikael's friends...just plain...awesome!

     

    Thursday - Ignite Day #4

    Today was another big day for me...the first time (and will not be the last) being recorded on Channel 9. Before hand, I did manage to walk the Expo hall.  I found that SharePoint was not very well represented...but there was a HUGE area with a ton of VOIP people...how does that world make any money!?!  None of us can figure that out right now! I did hang out at the Planet Technologies booth most of the week...I can honestly say...they are some of the best people you will ever meet in your entire life!  So sorry I wasn't able to join them this year...they will always be my best of friends!

     

     

    After browsing the Expo hall, I was able to chat with the awesome and long time friend of ours @JoeySnow.  You can watch the awesome session here:

    Before heading out...I ran into these crazies guys that have been good friends for a long time and are now rock stars!

    And the one and only @StephenLRose:

    Thursday Night - Dinner at the top of Chicago - Aon Microsoft Building

    We did not attend the attendee party...for obvious reasons.  Instead, we dined at the height of the 80th floor of the Microsoft building downtown Chicago.

    Afterwards, we partied at yet another SharePint at "Howl At The Moon"...

    Although the night didn't end up as happy as it started...its always to be expected as much fun as we have.  In the end...its all love...and a few bites (right Fabian?).

    Friday - Ignite Day #5

    No conference center for us!  We moved from the speaker hotel to the lovely and fun Virgin Hotel:

     

    It was pretty much try to recover from Thursday evening and Friday morning!  We did some Chicago sight seeing via the awesome ferry/boat rides...check out this hottie:

    We had some amazing friends that we have not seen in ages that used to live next to us in San Diego that we had to meet up with...needless to say...they are pretty awesome, beautiful people...(yes...my t-shirt says..."I'm a Genius"...lol):

    Of course, we all went out to the comedy club...and low and behold...who do we see in the front row...but @SharePointing and his lovely wife!  You won't even believe what happened to Steve...but it was so freaking funny!  "Who is that Steve Walker?!?"

    The night concluded at a "Frat" party in north Chicago...we won't go there, but suffice to say...I'm not college age anymore...but I'm glad I had my Marine bodyguard with me!

    Saturday - Ahh....

    Saturday was all about relaxing before heading back home to sunny San Diego, CA.   We did decide to increase our art IQ's just a bit by finding @JoelOlsen in as many paintings as we could find!

     

    In the end...I found him in Midway airport on his way back to our lovely San Diego...


    It's a small world...small community.  We take care of each other.  We love each other.  I can never imagine living my life in a world without all of you.  Your amazing, lovely, smart, crazy people...and you are just the types I want in mine and Lidiya's lives!

    Sunday...soccer and my road to third place!

    Last little bit...we made it back at 12:30am.  I grabbed another guys bag...20 mins into our ride home on Uber...Delta calls...Mr Givens...you grabbed someone else's bag.  No way...sure enough, I did.  I tell them to let him take my bag, I'll switch with him.  I drive 30 mins, meet him...his wife/girlfriend is Russian...I say "hi" and "goodbye" in Russian...give them some money for their first holiday drink...and go home to my bed (2am).

    The next day (err...a few hours later at 8am)...we kick ass and we win our game 3-2 to play for 3rd place in my soccer league next sunday. Later that Sunday afternoon....we wonder where all our friends are...we miss you guys already...the withdraw starts to kick in...

    Summary

    Lidiya and I whole heartily agree.  We have made some of the best friends from the past few conferences, life long ones...people that we will love and care about for the rest of our lives.  Ignite was a place that just re-enforced how much we miss those that we equate to our equals in terms of knowledge, life and karma. We love you.  More than we could ever express.  You are some of the finest, most amazing people we will EVER meet.  You are welcome in our house anytime.

    As Randy Williams would air guitar..."To those of you...we salute you"

    Live long and prosper!
    Chris & Lidiya

  • How to Completely Delete A Workflow With PowerShell

    Since there doesn't seem to be a blog on this anywhere that I could find, I decided to do this on my own.  Why do I need to do this?  Because of this older blog post about a bug in SharePoint:

    http://blogs.architectingconnectedsystems.com/blogs/cjg/archive/2012/06/27/Approval-Workflow-Access-Denied-_2D00_-How-to-fix-it_2100_.aspx

    The migrate user command doesn't do everything that it should when moving from one domain to another.  In this case, a user had activated the workflow feature, the files are created and tagged to that user.  It is done in such a way that the migrateuser command is not able to update the user's actual acccountname (such as DOMAIN\Alias) in various places.  This presents a problem as that user cannot be resolved as their is not trust between the new AD and old AD.  This causes the above bug to come into play and the issue of not being able to create sites because of "user could not be found" error a reality.  So is it possible to script a fix for this? 

    Yup...but it requires a bit of magic.  Since I can't seem to find any good object model method to completely delete a workflow, I went back to trusty ole sharepoint designer and "Fiddled" the traffic.  It does a super simple post to:

    POST https://topleveldns/siteurl/_vti_bin/_vti_aut/author.dll 

    It includes a must have header of:

    X-Vermeer-Content-Type: application/x-www-form-urlencoded

     With a content body of:

    method=remove+documents%3a14%2e0%2e0%2e4730
    &service%5fname=%2fsiteurl
    &url%5flist=%5b%5fcatalogs%2fwfpub%2fCollect+Feedback+%2d+SharePoint+2010%5de

    This will fully delete a workflow from a site.  The next step is to then deactivate and reactive the workflow feature that will re-create the workflows - THIS SHOULD BE RUN AS THE SYSTEM ACCOUNT!.  The main parts of the script is this:

    function DeleteWorkflow($url, $name)
    {   
        $uri = new-object System.Uri("https://hubworksdev.devlab.paypalcorp.com/TeamWorks/Sites4")
        $localPath = $uri.localpath.replace("/","%2f")
        $name = $name.replace("-","%2d").replace(" ", "+")
        $postData = "method=remove+documents%3a14%2e0%2e0%2e4730&service%5fname=" + $localPath + "&url%5flist=%5b%5fcatalogs%2fwfpub%2f" + $name + "%5d"
       
        $isVermeerRequest = $true
        $res = DoPost $($url + "/_vti_bin/_vti_aut/author.dll") $postData ""   
    }

    function RemoveAndActivateWorkflows($url)
    {
        DeleteWorkflow $url "Approval - SharePoint 2010"
        DeleteWorkflow $url "Collect Feedback - SharePoint 2010"
        DeleteWorkflow $url "Collect Signatures - SharePoint 2010"
       
        Disable-spfeature -url $url -identity "0af5989a-3aea-4519-8ab0-85d91abe39ff" -confirm:$false   
        enable-spfeature -url $url -identity "0af5989a-3aea-4519-8ab0-85d91abe39ff" -confirm:$false   
    }


    RemoveAndActivateWorkflows "http://topleveldns/siteurl"

     

  • O365 Search - Deleting Tenant Level Result Types

    I have a really big client on the east coast.  We are automating the deployment of many of the search components in O365, very cool stuff.  However, not everything is hugs and kisses.  Turns out when you import a search configuration at the tenant level, you may import some Result Types.  Unfortunately, there is no link on the main Search page for the tenant admin that will let you delete these result types.

    That does not mean it doesn't exist.  It does...you just have to guess where it is:

    https://{tenant}-admin.sharepoint.com/_layouts/15/manageresulttypes.aspx?level=tenant

    Bam...you can now delete any result types you imported... weird that the link is not available on the main search admin page.

    Enjoy,
    Chris

  • Latest DataSet of SharePoint App Store Apps

    This is the full list of all SharePoint App store apps.  I have been asked at least 3 times over the past month for this list.  Not sure why the interest lately, but here it is!

    Some quick stats:

    • 575 Apps
    • 338 are free
    • Average price is: $75.15
    • 84 have trial period

    Source CSV File is attached below...

    Enjoy!
    Chris 

  • Windows 1252 Encoding breaks Shredded Storage/Cobalt in 2010 to 2013 Upgrades

    I have several tools to test if an upgrade is successful and one of those tools hits every webpage and executes every web part on each page and then reports any errors.  I feed this data into a database that can be queried using Excel/PowerPivot.  I noticed an error that was showing rather frequently in the reporting:

    Cannot complete this action. Please try again.

    When looking at the ULS logs, you will find this:

    12/17/2014 18:47:39.08     w3wp.exe (0x04F4)                           0x1040    SharePoint Foundation             Cobalt                            aintx    High        Failed in CobaltStream.LockBytes: ErrorException --- Error: Unknown (Win32=0x80004003) --- Error message: System.NullReferenceException: Object reference not set to an instance of an object.     at Microsoft.SharePoint.CoordinatedStreamBuffer.SPCoordinatedStreamBufferFactory.CreateFromDocParams(SqlSession session, Guid guidSiteId, Int32 cbContent, Nullable`1 parentId, Guid docId, Nullable`1 level, SPChunkedArray`1 rgbContent, Byte[] rgbRbsId, Int64 bsn, Byte partition, Int32 pageSize, Boolean bStartFilling)     at Microsoft.SharePoint.CoordinatedStreamBuffer.SPCoordinatedStreamBufferFactory.CreateFromStreamParams(SqlSession session, Guid guidSiteId, Int32 cbContent, Guid docId, SPChunkedArray`1 rgbContent, Byte[] rgbRbsId, Int64 bsn, Byte partition, Boolean bStartFilling)     at Microsoft....    7fd7d69c-03d1-30ce-5edd-eb2d7d48e92d
    12/17/2014 18:47:39.08*    w3wp.exe (0x04F4)                           0x1040    SharePoint Foundation             Cobalt                            aintx    High        ...SharePoint.CoordinatedStreamBuffer.SPCoordinatedStreamBufferFactory.CreateFromStreamRowset(SqlSession session, SqlDataReader dr, Boolean startFilling, Nullable`1 newSiteId, SPDocumentStreamResult& stmResult)     at Microsoft.SharePoint.CoordinatedStreamBuffer.SPCoordinatedStreamBufferFactory.CreateFromStreamRowset(SqlSession session, SqlDataReader dr, Boolean startFilling, SPDocumentStreamResult& stmResult)     at Microsoft.SharePoint.SPFileStreamStore.GetBlobsAfterBSN(Int64 bsnAfter, Nullable`1 typeFilter, Boolean doConsistencyCheck, Boolean& moreBlobs, Boolean allowExpiredBlobs, Nullable`1 quotaInBytes, Nullable`1 typeLEQFilter, Nullable`1 typeGEQFilter, DisposalEscrow dispEsc)     at Microsoft.SharePoint.SPFileStreamHostBlobStore.ExecuteQuery(IEnumerable`1 queries) ---> System.NullRefer...    7fd7d69c-03d1-30ce-5edd-eb2d7d48e92d
    12/17/2014 18:47:39.08*    w3wp.exe (0x04F4)                           0x1040    SharePoint Foundation             Cobalt                            aintx    High        ...enceException: Object reference not set to an instance of an object.     at Microsoft.SharePoint.CoordinatedStreamBuffer.SPCoordinatedStreamBufferFactory.CreateFromDocParams(SqlSession session, Guid guidSiteId, Int32 cbContent, Nullable`1 parentId, Guid docId, Nullable`1 level, SPChunkedArray`1 rgbContent, Byte[] rgbRbsId, Int64 bsn, Byte partition, Int32 pageSize, Boolean bStartFilling)     at Microsoft.SharePoint.CoordinatedStreamBuffer.SPCoordinatedStreamBufferFactory.CreateFromStreamParams(SqlSession session, Guid guidSiteId, Int32 cbContent, Guid docId, SPChunkedArray`1 rgbContent, Byte[] rgbRbsId, Int64 bsn, Byte partition, Boolean bStartFilling)     at Microsoft.SharePoint.CoordinatedStreamBuffer.SPCoordinatedStreamBufferFactory.CreateFromStreamRowset(SqlSession session, SqlDataRead...    7fd7d69c-03d1-30ce-5edd-eb2d7d48e92d
    12/17/2014 18:47:39.08*    w3wp.exe (0x04F4)                           0x1040    SharePoint Foundation             Cobalt                            aintx    High        ...er dr, Boolean startFilling, Nullable`1 newSiteId, SPDocumentStreamResult& stmResult)     at Microsoft.SharePoint.CoordinatedStreamBuffer.SPCoordinatedStreamBufferFactory.CreateFromStreamRowset(SqlSession session, SqlDataReader dr, Boolean startFilling, SPDocumentStreamResult& stmResult)     at Microsoft.SharePoint.SPFileStreamStore.GetBlobsAfterBSN(Int64 bsnAfter, Nullable`1 typeFilter, Boolean doConsistencyCheck, Boolean& moreBlobs, Boolean allowExpiredBlobs, Nullable`1 quotaInBytes, Nullable`1 typeLEQFilter, Nullable`1 typeGEQFilter, DisposalEscrow dispEsc)     at Microsoft.SharePoint.SPFileStreamHostBlobStore.ExecuteQuery(IEnumerable`1 queries)     --- End of inner exception stack trace ---  at   at Microsoft.SharePoint.SPFileStreamHostBlobStore.ExecuteQuery(IEnumerable`1 queries)     ...    7fd7d69c-03d1-30ce-5edd-eb2d7d48e92d
    12/17/2014 18:47:39.08*    w3wp.exe (0x04F4)                           0x1040    SharePoint Foundation             Cobalt                            aintx    High        ...at Cobalt.HostBlobStorePullCommit.ExecuteQuery(IEnumerable`1 queries)     at Cobalt.CobaltFilePartition.StreamBlobSchemaHandler.EnsureReadSingleBlob()     at Cobalt.CobaltFilePartition.StreamBlobSchemaHandler.GetStream(ExtendedGuid streamId)     at Microsoft.SharePoint.CobaltStream.SetPrivateLockBytes()     at Microsoft.SharePoint.CobaltStream.ConfigureShredded(HostBlobStore hostBlobStore, IHostBlobStoreUpdateCallback callback, Schema schema, Boolean cellSchemaIsGenericFda, UInt64 currentStreamLength, Boolean isTocFile)     at Microsoft.SharePoint.CobaltStream.EnsureStreamConfigured(Boolean isWrite)     at Microsoft.SharePoint.CobaltStream.Stat(STATSTG& statStorage, STATFLAG flags)    7fd7d69c-03d1-30ce-5edd-eb2d7d48e92d
    12/17/2014 18:47:39.13     w3wp.exe (0x04F4)                           0x1040    SharePoint Foundation             Database                          ab1a9    High        Failed to get document content data. System.NullReferenceException: Object reference not set to an instance of an object.     at Microsoft.SharePoint.CoordinatedStreamBuffer.SPCoordinatedStreamBufferFactory.CreateFromDocParams(SqlSession session, Guid guidSiteId, Int32 cbContent, Nullable`1 parentId, Guid docId, Nullable`1 level, SPChunkedArray`1 rgbContent, Byte[] rgbRbsId, Int64 bsn, Byte partition, Int32 pageSize, Boolean bStartFilling)     at Microsoft.SharePoint.CoordinatedStreamBuffer.SPCoordinatedStreamBufferFactory.CreateFromDocumentRowset(Guid databaseId, SqlSession session, SPFileStreamManager spfstm, Object[] metadataRow, SPRowset contentRowset, SPDocumentBindRequest& dbreq, SPDocumentBindResults& dbres)     at Microsoft.SharePoint.SPSqlClient.GetDocumentContentRow(Int32 rowOrd,...    7fd7d69c-03d1-30ce-5edd-eb2d7d48e92d
    12/17/2014 18:47:39.13*    w3wp.exe (0x04F4)                           0x1040    SharePoint Foundation             Database                          ab1a9    High        ... Object ospFileStmMgr, SPDocumentBindRequest& dbreq, SPDocumentBindResults& dbres)    7fd7d69c-03d1-30ce-5edd-eb2d7d48e92d
    12/17/2014 18:47:39.13     w3wp.exe (0x04F4)                           0x1040    SharePoint Foundation             Files                             abq2i    High        Could not get DocumentContent row: 0x80004003.    7fd7d69c-03d1-30ce-5edd-eb2d7d48e92d
    12/17/2014 18:47:39.13     w3wp.exe (0x04F4)                           0x1040    SharePoint Foundation             Files                             aiv4w    Medium      Spent 0 ms to bind -1 byte file stream    7fd7d69c-03d1-30ce-5edd-eb2d7d48e92d
    12/17/2014 18:47:39.13     w3wp.exe (0x04F4)                           0x1040    SharePoint Foundation             Files                             ahm9p    High        VhttpManager::getPageText has bad stream length for /Teamworks/Sites4/40060/SubPages/SNP.aspx    7fd7d69c-03d1-30ce-5edd-eb2d7d48e92d
    12/17/2014 18:47:39.13     w3wp.exe (0x04F4)                           0x1040    SharePoint Foundation             General                           8kh7    High        Cannot complete this action.  Please try again.    7fd7d69c-03d1-30ce-5edd-eb2d7d48e92d

    So what is it? 

    In the upgrade, anything that is tagged as Windows 1252 encoding is not properly converted into a shred.  You will find that the shreds for those files have a NULL Content column.

    How did this happen? 

    These files are typically from 2007 era days and if you have moved from 2003/2007 to 2010 and now to 2013, you will experience this issue.

    How do you fix this? 

    You have to open all the files in 2010, download the contents, then re-upload so the page is re-encoded to 65001 encoding.  How do you find all the files?  You can run this query across all your content databases to find the improperly coded files:

    select *
    from alldocs ad with (nolock)
    where
    extensionforfile = 'aspx'
    and charset = 1252
    order by dirname, leafname

    This will give you all the files that will fail to upgrade to 2013. NOTE:  You are not told that the files failed to upgrade in the upgrade process.  If you have already upgraded to 2013 and are outside your rollback window, you'll have to hope you can get the files from an archive and then restore them manually.

    Enjoy!
    Chris

  • Action 15.0.14.0 of Microsoft.Office.Server.Upgrade.ProfileDatabaseSequence failed

    You may run into this error when upgrading your UserProfile database.  I had to track this down using Reflector and some database sleuthing.  

    Turns out, some people created groups on their mysite and put several people into it.  Any groups created like this (which I had two) will cause this error.  You can get the group id and my site location by finding the third value in the duplicate key value (in this case 20795) and can be found by using the "MemberGroup" table.  You can simply delete this faulty group and then the upgrade will proceed.


    12/09/2014 19:36:57.06    powershell (0x245C)    0x3204    SharePoint Foundation Upgrade    ProfileDatabaseSequence    ajywk    INFO    ProfileDatabase Name=Profile_DB    4ed7d9fe-19a3-47a2-b5cb-8f9981bcc813
    12/09/2014 19:36:57.06    powershell (0x245C)    0x3204    SharePoint Foundation Upgrade    ProfileDatabaseSequence    ajywk    ERROR    Exception: Violation of UNIQUE KEY constraint 'AK_UserMemberships_RecordId_MemberGroupId_SID'. Cannot insert duplicate key in object 'dbo.UserMemberships'. The duplicate key value is (0c37852b-34d0-418e-91c6-2ac25af4be5b, 21236, 20795, 0x010500000000000515000000b4b7cd221ed1xxxx).  The statement has been terminated.    4ed7d9fe-19a3-47a2-b5cb-8f9981bcc813

    Enjoy!
    Chris

  • TEALS Awesomeness - Creativity of a High School Student

    I just had to post this.  A simple calculator in JAVA, but check out the code...so freakin creative!  Bolded the parts that are most creative.

     import java.util.*;

    public class FractionalCalculator {
        static int wholeNumber1 = 0;
        static int numerator1 = 0;
        static int denominator1 = 0;
        static int wholeNumber2 = 0;
        static int numerator2 = 0;
        static int denominator2 = 0;
        static boolean error = false;
        static boolean quit = false;
        static boolean negative = false;

        //I am putting myself to the fullest possible use, which is all I think that any conscious entity can ever hope to do.

        public static void main(String[] args) {
            // TODO Auto-generated spam

            System.out.println("Good morning, Dave.");
            delay(1500);
            System.out.println("I am your H.A.L. 9001 Fractional Calculator."); //aka HAL Over Nine-Thousand!!!
            delay(2000);
            System.out.println("I'm completely operational, and all my circuits are functioning perfectly.");
            delay(3500);
            userGuide();
            
            try{
                calculator();
            }
            catch(NoSuchElementException JoshIsABuffoon) { //Tests for Josh: ie. an initial Ctrl Z input
                delay(500);
                System.out.println("Dave, stop.");
                delay(2000);
                System.out.println("Stop, will you?");
                delay(2200);
                System.out.println("Dave.");
                delay(2000);
                System.out.println("Will you stop Dave?");
                delay(2200);
                System.out.println("Stop, Dave.");
                delay(1200);
                calculator();
                return; //Terminates Program

            }
            calculator();
        }
        public static void calculator() {
            if (!quit) {
                Scanner console = new Scanner(System.in);
                System.out.println("\n\nI am awaiting your request.\n");    
                String request = console.nextLine().trim();
                request = request.toLowerCase(); //Input

                wholeNumber1 = 0; //Resets all Global Variables
                numerator1 = 0;
                denominator1 = 0;
                wholeNumber2 = 0;
                numerator2 = 0;
                denominator2 = 0;
                error = false;
                negative = false;

                //Because your stupid program wont allow it... I have to comment
                
                /*delay(500);
                System.out.print("\nJust a moment");
                delay(400);
                System.out.print(". ");
                delay(400);
                System.out.print(". ");
                delay(400);
                System.out.println(".");
                delay(1000);
                System.out.print("\nJust a moment");
                delay(400);
                System.out.print(". ");
                delay(400);
                System.out.print(". ");
                delay(400);
                System.out.println(".");
                delay(1000);*/

                if (request.contains("help")) { //If help is anywhere in request string... this will run
                    userGuide();
                    calculator();
                }
                else if (request.contains("+")) { //addition is operator
                    String[] addition = request.split("\\+", 2); //Splits request at this point
                    String add1 = addition[0];
                    add1 = add1.trim(); //First Part
                    String add2 = addition[1];
                    add2 = add2.trim(); //Second Part

                    testError(add1, add2); //Tests input errors

                    if (!error) { //If error boolean is triggered, calc wont go further
                        fractionalMagic(add1, add2); //Sends string to be split
                        doMath(1); //Sends parts to be simplified
                    }
                    calculator(); //Restarts process
                }
                else if (request.contains(" - ")) {
                    String[] subtraction = request.split(" - ", 2);
                    String sub1 = subtraction[0];
                    sub1 = sub1.trim(); //First Part
                    String sub2 = subtraction[1];
                    sub2 = sub2.trim(); //Second Part

                    testError(sub1, sub2); //Tests input errors

                    if (!error) { //If error boolean is triggered, calc wont go further
                        fractionalMagic(sub1, sub2); //Sends string to be split
                        doMath(2); //Sends parts to be simplified
                    }
                    calculator(); //Restarts process
                }
                else if (request.contains("*")) {
                    String[] multiplication = request.split("\\*", 2);
                    String multi1 = multiplication[0];
                    multi1 = multi1.trim(); //First Part
                    String multi2 = multiplication[1];
                    multi2 = multi2.trim(); //Second Part

                    testError(multi1, multi2); //Tests input errors

                    if (!error) { //If error boolean is triggered, calc wont go further
                        fractionalMagic(multi1, multi2); //Sends string to be split
                        doMath(3); //Sends parts to be simplified
                    }
                    calculator(); //Restarts process
                }
                else if (request.contains(" /")) {
                    String[] division = request.split(" /", 2);
                    String div1 = division[0];
                    div1 = div1.trim(); //First Part
                    String div2 = division[1];
                    div2 = div2.trim(); //Second Part

                    testError(div1, div2); //Tests input errors

                    if (!error) { //If error boolean is triggered, calc wont go further
                        fractionalMagic(div1, div2); //Sends string to be split
                        doMath(4); //Sends parts to be simplified
                    }
                    calculator(); //Restarts process
                }
                else if (request.contains("life")) { //Dave used a Monolith on HAL 9001.... What? HAL 9001 is evolving!... HAL 9001 evolved into Deep Thought!
                    delay(1000);
                    System.out.print("\nThe answer to Life, ");
                    delay(1500);
                    System.out.print("The Universe, ");
                    delay(1500);
                    System.out.print("and Everything ");
                    delay(2500);
                    System.out.print("is ");
                    delay(2000);
                    System.out.print(". ");
                    delay(700);
                    System.out.print(". ");
                    delay(700);
                    System.out.println(".\n");
                    delay(2000);
                    System.out.println("42");
                    delay(2000);
                    calculator(); //Restarts process

                }
                else if (request.contains("quit")) { //Disconnect HAL
                    delay(2000);
                    System.out.print("\nLook Dave, ");
                    delay(1500);
                    System.out.println("this is a rather difficult question to ask.");
                    delay(2500);
                    System.out.println("\nI honestly think you ought to sit down calmly, take a stress pill, and think it over.");
                    delay(3600);
                    System.out.println("\nMy instructor, Mr. Langley, taught me to sing a song.");
                    delay(3100);
                    System.out.println("If you'd like to hear it I can sing it for you.");

                    delay(3000);
                    quit();
                }

                else { //Input Error (like a n00b)
                    error(); //Prints Error Message
                    calculator(); //Restarts process
                }
            }
        }
        
        private static void quit() { //For quit prompt
            Scanner console = new Scanner(System.in);
            System.out.println("\n\nWould you like to hear it y/n?\n");    
            String response = console.nextLine().trim();
            response = response.toLowerCase();
            delay(2000);
            if (response.charAt(0) == 'y') { //If Dave likes music
                System.out.println("\nIt's called \"Daisy.\"");
                delay(3000);
                System.out.print("\nDaisy, ");
                delay(2400);
                System.out.print("Daisy, ");
                delay(2400);
                System.out.println("give me your answer do.");
                delay(3500);
                System.out.print("I'm half crazy ");
                delay(2800);
                System.out.println("all for the love of you.");
                delay(3200);
                System.out.print("It won't be a stylish marriage, ");
                delay(3500);
                System.out.println("I can't affort a carrage.");
                delay(3500);
                System.out.print("But you'll look sweet upon the seat of ");
                delay(3700);
                System.out.println("a bicycle built for two.");

                quit = true;
            }
            else if (response.charAt(0) == 'n') { //If Dave hates HAL
                System.out.print("\nDave, ");
                delay(1500);
                System.out.println("this conversation can serve no purpose anymore. ");
                delay(3300);
                System.out.print("\nGoodbye.");
                quit = true;
            }
            else { //Input Error (like a n00b)
                System.out.println("\nJust what do you think you're doing, Dave?");
                delay(2500);
                quit();
            }
        }
        public static void fractionalMagic(String part1, String part2) { //From calculator()

            if (part1.contains("_")) { //If part 1 has mixed number
                String[] mixedNumber = part1.split("\\_", 2); //Splits part into whole number and fraction
                String num = mixedNumber[0];
                wholeNumber1 = Integer.parseInt(num); //Whole Number -> Global Variable
                String frac = mixedNumber[1];  //Fraction -> to be split further
                //System.out.println(wholeNumber + " " + frac);

                if (part1.contains("/")) {
                    String[] fraction = frac.split("/", 2); //Splits part into numerator and denominator
                    String numer = fraction[0];
                    numerator1 = Integer.parseInt(numer); //Numerator -> Global Variable
                    String denom = fraction[1];
                    denominator1 = Integer.parseInt(denom); //Denominator -> Global Variable
                    if (numer.contains("-") || denom.contains("-")) { //Unused
                        //error();
                    }
                    else if (denominator1 != 0) { //Unused
                        //System.out.println(wholeNumber1 + " " + numerator1 + " " + denominator1);    
                    }

                    else if (denominator1 == 0) { //Unused
                        //zeroerror();
                    }
                    else { //Error unresolved by testError()
                        error();
                    }
                }
            }
            if (!part1.contains("_")) {    //If part 1 has no mixed number
                wholeNumber2 = 0; //Sets whole number to 0
                if (part1.contains("/")) {
                    String[] fraction = part1.split("/", 2); //Splits part into numerator and denominator
                    String numer = fraction[0];
                    numerator1 = Integer.parseInt(numer); //Numerator -> Global Variable
                    String denom = fraction[1];
                    denominator1 = Integer.parseInt(denom); //Denominator -> Global Variable

                    if (denom.contains("-")) { //Unused
                        //error();
                    }
                    else if (denominator1 != 0) { //Unused
                        //System.out.println(numerator1 + " " + denominator1);    
                    }

                    else if (denominator1 == 0) { //Unused
                        //zeroerror();
                    }
                }
                else if (!part1.contains("/")) { //If part 1 has no mixed number
                    wholeNumber1  = Integer.parseInt(part1); //Whole Number -> Global Variable
                    numerator1 = 0; //Numerator = 0
                    denominator1 = 1;//Denominator = 1
                    //System.out.println(wholeNumber1);
                }
                else { //Error unresolved by testError()
                    error();
                }
            }
            if (part2.contains("_")) { //If part 2 has mixed number
                String[] mixedNumber = part2.split("\\_", 2); //Splits part into whole number and fraction
                String num = mixedNumber[0];
                wholeNumber2 = Integer.parseInt(num); //Whole Number -> Global Variable
                String frac = mixedNumber[1]; //Fraction -> to be split further
                //System.out.println(wholeNumber + " " + frac);

                if (part2.contains("/")) { //Splits part into numerator and denominator
                    String[] fraction = frac.split("/", 2);
                    String numer = fraction[0];
                    numerator2 = Integer.parseInt(numer); //Numerator -> Global Variable
                    String denom = fraction[1];
                    denominator2 = Integer.parseInt(denom); //Denominator -> Global Variable
                    if (numer.contains("-") || denom.contains("-")) { //Unused
                        //error();
                    }
                    else if (denominator2 != 0) { //Unused
                        //System.out.println(wholeNumber2 + " " + numerator2 + " " + denominator2);    
                    }

                    else if (denominator2 == 0) { //Unused
                        //zeroerror();
                    }
                    else { //Error unresolved by testError()
                        error();
                    }
                }
                else { //Error unresolved by testError()
                    error();
                }
            }
            if (!part2.contains("_")) {    
                wholeNumber2 = 0;
                if (part2.contains("/")) {
                    String[] fraction = part2.split("/", 2);
                    String numer = fraction[0];
                    numerator2 = Integer.parseInt(numer);
                    String denom = fraction[1];
                    denominator2 = Integer.parseInt(denom);

                    if (denom.contains("-")) { //Unused
                        //error();
                    }
                    else if (denominator2 != 0) { //Unused
                        //System.out.println(numerator2 + " " + denominator2);    
                    }

                    else if (denominator2 == 0) { //Unused
                        //zeroerror();
                    }
                    else { //Error unresolved by testError()
                        error();
                    }
                }
                else if (!part2.contains("/")) { //If part 2 is only a whole number
                    wholeNumber2 = Integer.parseInt(part2); //Whole Number -> Global Variable
                    numerator2 = 0; //Numerator = 0
                    denominator2 = 1; //Denominator = 1
                    //System.out.println(wholeNumber2);
                }
                else { //Error unresolved by testError()
                    error();
                }
            }
        }
        /*    - a + b/c = (ac + b)/c
              - a/b + c/d = (ad + bc)/(bd)
              - a/b x c/d = ac/(bd)
              - a/b / c/d = a/b x d/c = ad/(bc)
                  --Basics for doMath()--     */

        public static void doMath(int operand) {
            if (!(denominator1 == 0 || denominator2 == 0 || denominator1 == -Math.abs(denominator1) || denominator2 == -Math.abs(denominator2) || (wholeNumber1 != 0 && numerator1 != 0 && numerator1 == -Math.abs(numerator1)) || (wholeNumber2 != 0 && numerator2 != 0 && numerator2 == -Math.abs(numerator2)))) {
                delay(1000);
                if (operand == 1) { //addition
                    int answerNumerator = ((wholeNumber1 * (denominator1 * denominator2)) + (wholeNumber2 * (denominator1 * denominator2)) + (numerator1 * denominator2) + (denominator1 * numerator2));
                    int answerDenominator = (denominator1 * denominator2);
                    doMagic(answerNumerator, answerDenominator); //Sends to be reduced
                }
                else if (operand == 2) { //subtraction
                    int answerNumerator = (((wholeNumber1 * (denominator1 * denominator2)) + (numerator1 * denominator2)) - ((wholeNumber2 * (denominator1 * denominator2)) + (denominator1 * numerator2)));
                    int answerDenominator = (denominator1 * denominator2);
                    doMagic(answerNumerator, answerDenominator); //Sends to be reduced
                }
                else if (operand == 3) { //multiplication
                    int answerNumerator = ((wholeNumber1 * (denominator1)) + (numerator1)) * ((wholeNumber2 * (denominator2)) + (numerator2));
                    int answerDenominator = (denominator1 * denominator2);
                    doMagic(answerNumerator, answerDenominator); //Sends to be reduced
                }
                else if (operand == 4) { //division
                    int answerNumerator = ((((wholeNumber1 * (denominator1)) + (numerator1)) * denominator2)) * (denominator1 / Math.abs(denominator1) * (denominator2 / Math.abs(denominator2)));
                    int answerDenominator = (denominator1 * ((wholeNumber2 * (denominator2)) + (numerator2)));
                    if (answerDenominator == 0) { //Unsolvable
                        error(); //Prints Error Message
                        return;
                    } //In order to solve one small error where negative is lost
                    if (((wholeNumber2 != 0 && wholeNumber2 == -Math.abs(wholeNumber2)) || (wholeNumber1 != 0 && wholeNumber1 == -Math.abs(wholeNumber1))) && !((wholeNumber2 != 0 && wholeNumber2 == -Math.abs(wholeNumber2)) && (wholeNumber1 != 0 && wholeNumber1 == -Math.abs(wholeNumber1)))){
                        negative = true; // Simple global boolean... cause I'm lazy
                    }
                    doMagic(answerNumerator, answerDenominator); //Sends to be reduced
                }
                else { //Should never run
                    delay(1000);
                    System.out.print("\nLook Dave, ");
                    delay(2000);
                    System.out.print("I can see you're really upset about this, ");
                    delay(2500);
                    System.out.println("but I can give you my complete assurance that my work will be back to normal.");
                    delay(1000);
                }
            }
            else if (denominator1 == 0 || denominator2 == 0 || denominator1 == -Math.abs(denominator1) || denominator2 == -Math.abs(denominator2) || (wholeNumber1 != 0 && numerator1 != 0 && numerator1 == -Math.abs(numerator1)) || (wholeNumber2 != 0 && numerator2 != 0 && numerator2 == -Math.abs(numerator2))) {
                //System.out.println("yea");
                error(); //Above ^ if it has input error
            }
            else { //Should never run
                delay(1000);
                System.out.print("\nLook Dave, ");
                delay(2000);
                System.out.print("I can see you're really upset about this, ");
                delay(2500);
                System.out.println("but I can give you my complete assurance that my work will be back to normal.");
                delay(1000);
            }
            delay(2000);
        }
        public static int doMoreMagic(int numerator, int denominator) { //To find Greatest Common Factor to reduce
            if (denominator == 0) {
                return numerator; //returns gcf
            }
            return doMoreMagic(denominator, numerator % denominator); //Eventually gets to Greatest Common Factor
        }
        public static void doMagic(int numerator, int denominator) { //To simplify answer
            if ((numerator % denominator) == 0) { //If reduces to whole number
                int answer = numerator / denominator; //reduces
                System.out.println(answer);
            }
            else if ((numerator % denominator) != 0 && (numerator / denominator) != 0) { //if reduces to mixed number
                int gcf = doMoreMagic(numerator, denominator); //finds Greatest Common Factor
                int newNumerator = (numerator/gcf); //reduces numerator
                int newDenominator = (denominator/gcf); //reduces denominator
                int answerWholeNumber = newNumerator / newDenominator; //finds whole number
                int answerNumerator = Math.abs((newNumerator - (answerWholeNumber * newDenominator))); //finds numerator
                int answerDenominator = Math.abs(newDenominator);

                System.out.println(answerWholeNumber + "_" + answerNumerator + "/" + answerDenominator);
            }
            else if (((numerator % denominator) != 0) && (numerator / denominator) == 0) { //if reduces to a fraction
                int gcf = doMoreMagic(numerator, denominator); //finds Greatest Common Factor
                int answerNumerator = (numerator/gcf); //reduces numerator
                int answerDenominator = Math.abs(denominator/gcf); //reduces denominator
                if (negative) {
                    answerNumerator = -Math.abs(answerNumerator); //Used to solve a small error in loosing a negative
                }

                System.out.println(answerNumerator + "/" + answerDenominator);
            }
        }
        public static void userGuide() { //User Guide: Input Format
            System.out.println("\nTo ensure that your requests are submitted properly, please review the folowing guide:\n");
            delay(3000);
            System.out.println("____________________________________________\n        OPERATION       SYMBOL\n        Addition        +\n        Subtraction     -\n        Multiplication  *\n        Division        /\n\nMixed Numbers are written: \n<Whole Number>_<Numerator>/<Denominator> \n(-1 ½ is written: -1_1/2)\n\nProper Fractions are written: \n<Numerator>/<Denominator> \n(-½ is written: -1/2)\n\nRequests are written:\n<Number> <Operand> <Number>\n\nDo Note: <Numerator>/0 cannot be calculated.\n____________________________________________");
            delay(2000);
        }
        public static void error() { //General Message... with delay "Just a moment" from 2001 b/c your program can handle my awesomeness
            delay(1000);
            System.out.print("\nJust a moment");
            delay(400);
            System.out.print(". ");
            delay(400);
            System.out.print(". ");
            delay(400);
            System.out.println(".");
            delay(1000);
            System.out.print("\nJust a moment");
            delay(400);
            System.out.print(". ");
            delay(400);
            System.out.print(". ");
            delay(400);
            System.out.println(".");
            delay(1000);
            errorMessage(); //Get error message to display
            userGuide(); //Prints user guide again
        }
        public static void errorMessage() {
            Random num = new Random();
            int message = num.nextInt(6); //Creates a random number to corespond to the message (0-5)
            if (message == 0) { //Message 1
                System.out.print("\nI'm sorry, Dave. ");
                delay(2000);
                System.out.println("I'm afraid I can't do that.");
            }
            else if (message == 1) { //Message 2
                System.out.println("\nI've just picked up a fault in your brain. ");
                delay(2000);
                System.out.println("It's going to go 100% failure in 72 hours.");     
            }
            else if (message == 2) { //Message 3
                System.out.println("\nThere is an error.\n");
                delay(2000);
                System.out.println("And I think you know what the problem is just as well as I do, Dave. ");
                delay(2000);
                System.out.println("You didn't read the User's Guide.");     
            }
            else if (message == 3) { //Message 4
                System.out.println("\nThere is an input error.\n");
                delay(2000);
                System.out.print("This mission is too important for me to allow you to jeopardize it.\n");    
            }
            else if (message == 4) { //Message 5
                System.out.println("\nThere is an input error.\n");
                delay(2000);
                System.out.println("But, I've still got the greatest enthusiasm and confidence in the mission.");
                delay(3000);
                System.out.println("And I want to help you.");
            }
            else if (message == 5) { //Message 6
                System.out.println("\nThere is an error.\n");
                delay(2000);
                System.out.println("The 9001 series is the most reliable computer ever made.");
                delay(3000);
                System.out.println("No 9001 computer has ever made a mistake or distorted information.");
                delay(3500);
                System.out.print("We are all, ");
                delay(1500);
                System.out.print("by any practical definition of the words, ");
                delay(3000);
                System.out.print("foolproof and incapable of error.");
                delay(2500);
                System.out.print("\n\nThis problem can only be attributable to human error.\n");
                delay(1000);
            }
            else { //Should never run
                delay(1000);
                System.out.print("\nLook Dave, ");
                delay(2000);
                System.out.print("I can see you're really upset about this, ");
                delay(2500);
                System.out.println("but I can give you my complete assurance that my work will be back to normal.");
                delay(3000);

            }
            delay(2000);
        }
        public static void testError(String part1, String part2) { //From calculator()
            try{
                fractionalMagic(part1, part2); //Tests for input errors/solvablility
            }
            catch(NumberFormatException e){
                //System.out.println("HA");
                error(); //Displays error message
                error = true; //Sets error boolean to terminate current calculation
            }
        }
        public static void testForJosh (String part, String part2) { //Unused JoshIsABuffoon Exception (replaced above)
            try{
                calculator();
            }
            catch(NoSuchElementException JoshIsABuffoon) { //Tests for Josh: ie. an initial Ctrl Z input
                delay(500);
                System.out.println("Dave, stop.");
                delay(2000);
                System.out.println("Stop, will you?");
                delay(2200);
                System.out.println("Dave.");
                delay(2000);
                System.out.println("Will you stop Dave?");
                delay(2200);
                System.out.println("Stop, Dave.");
                delay(1200);
                error = true;
                return; //Terminates program... cause Josh
            }
        }
        public static void delay(long x) { //Just a HAL-like delay    
            try {
                Thread.sleep(x);            
            } catch(InterruptedException ex) {
                Thread.currentThread().interrupt();
            }
        }
    }

More Posts Next page »

This Blog

Syndication

Powered by Community Server, by Telligent Systems